SecureBite API Proxy

Frequently Asked Questions

Common questions about security, privacy, and how the proxy works.

Can someone call the proxy endpoints from outside my store?

No. The proxy URLs (/apps/proxy/...) only exist on your Shopify storefront. When a request comes in, Shopify’s App Proxy gateway signs it with a cryptographic HMAC signature using your app’s secret key. The Cloudflare Worker verifies this signature before processing any request.

If someone tries to call the Worker URL directly (bypassing Shopify), the request has no valid signature and is immediately rejected with a 401 Unauthorized. There is no way to forge this signature without your app’s secret.

Can a storefront visitor abuse or misuse my proxy routes?

A visitor browsing your store (or using the browser console) can call your configured proxy routes - that’s by design, since your theme code needs to call them too. However, they can only hit the exact routes you configured with the exact target URLs and methods you defined. They cannot change the destination, inject different headers, or access other merchants’ data.

All proxy routes are also rate-limited to 120 requests per minute per route, and on routes that require login each customer gets at most 30 per minute. Monthly usage is capped by your plan limit, so even automated abuse is bounded.

Can visitors see my API keys or secret headers?

No. API keys and secret headers are stored in Cloudflare KV and injected server-side by the Worker. They never appear in the HTML source, JavaScript bundles, network responses, or browser DevTools. The storefront visitor only sees the final API response data - never the credentials used to fetch it.

This is the entire purpose of the app: keeping your API keys completely hidden from client-side code.

How do I find API keys already exposed in my theme?

Open Theme Scan in the app and click Run scan. It checks every file in your published theme for known secret patterns (Stripe, AWS, Klaviyo, OpenAI and many more) and skips keys that are public by design, such as Stripe publishable keys. We don’t store the matches.

For each finding, move that API call to a SecureBite route, then create a new key with the provider and delete the old one, since anyone may already have copied it. On Pro and Scale, our team can do the cleanup for you.

Is it safe to use POST routes that modify data?

Your API keys stay hidden regardless of the HTTP method. However, for routes that write or modify data (POST, PUT, PATCH), be aware that any visitor on your store could potentially call that endpoint from the browser console. To mitigate this:

For highly sensitive write operations (payments, account creation), a dedicated backend with full user authentication is recommended over any client-side proxy.

What is the nonce / CSRF protection and how do I use it?

The nonce system prevents replay attacks and console-scripted spam on POST routes. When enabled, the frontend must get a single-use token before submitting data:

  1. Frontend calls GET /apps/proxy/{route}?_action=nonce to receive a nonce, timestamp, and cryptographic signature.
  2. Frontend includes _nonce, _nonce_ts, and _nonce_sig in the POST body alongside the form data.
  3. The Worker verifies the signature, checks the nonce is less than 60 seconds old, and confirms it hasn’t been used before.
  4. Nonce fields are automatically stripped before forwarding to the upstream API.

This means each POST needs its own unique GET request first. Console-based spam scripts are slowed to one request at a time, and replaying a captured request always fails because the nonce is single-use.

What is the body template and why should I use it?

A body template lets you define the exact JSON structure that gets sent to the upstream API. Instead of the frontend controlling the full payload, it only sends simple field values (like name and email). The Worker merges these into your template server-side.

Benefits:

How do I stop visitors changing what a route asks the API for?

By default, query parameters the storefront sends (for example ?filter=… or ?page[size]=100) are passed on to your API. Anyone can edit those in the browser.

Turn on Forward only mapped params on the route. Every storefront parameter is then dropped, except those you use in a {{placeholder}} or a parameter mapping. Your secret query params are still added. Callers can no longer slip in their own filters, extra fields or paging.

If your storefront currently sends a value the API needs, such as a filter, set up its server-side replacement (a secret param) in the same save as you turn this on.

Can I put a value from the storefront into the API URL, like a profile ID?

Yes. Write {{name}} in the path of the Target API URL, for example https://a.klaviyo.com/api/profiles/{{p}}/. It is filled from the storefront query parameter of the same name: /apps/proxy/your-route?p=01HZX4….

Can SecureBite cache API responses so pages load faster?

Yes, on the Pro and Scale plans (each has a 14-day free trial). Set Cache responses on a GET route and repeat requests get a stored copy instead of calling the API again. It works with any API and for every visitor, logged in or not. Requests that send different values to the API (another product, search term or customer) get separate copies, so a customer’s own data is only ever returned to them. Cached responses count toward your monthly requests.

SecureBite only sees changes that go through its own routes, so match the fix to where a change comes from:

How do I return only part of the API’s response?

Set Return only on the route to a path in the JSON response, for example data.attributes.properties. The visitor then receives only that part: { "properties": { … } }. Everything else the API returns, such as emails, IDs or internal fields, never reaches the browser.

If the API returns an error, the status code is passed on with a short message such as { "error": "not_found" }, instead of the API’s full error details.

How can a route return only the logged-in customer’s own data?

Let SecureBite decide who the customer is, instead of trusting what the browser sends:

Whatever filter the browser sends is then ignored, and the route can only ever return that customer’s own record. To match by email instead, use filter = equals(email,"{{logged_in_customer_email}}"). SecureBite looks the email up from Shopify on the server, so it can’t be faked either.

Klaviyo’s Get Events filters by profile ID, not email. On a route to a.klaviyo.com with Require logged-in customer on, use filter = equals(profile_id,"{{klaviyo_profile_id}}"). SecureBite finds the customer’s Klaviyo profile from their email with the route’s own Klaviyo headers, then makes the call. If the customer has no Klaviyo profile, the route returns {"data": []}. A request that needs this lookup counts as 2 requests.

Which protections should I turn on?

The route editor’s help text explains each option, and Shopify Sidekick can review a route’s security for you.

Where are your terms, privacy and security policies?

Using SecureBite means you accept our Terms of Service, which include a data processing addendum for your customers’ data. Our Privacy Policy explains what we store and for how long, and our Security Incident Response Policy explains how we handle and report incidents.

Can Shopify Sidekick set up a route for me?

Yes. Open Sidekick in your Shopify admin and paste your API call: a curl command, code or an example from the API’s docs. Sidekick turns it into a route and gives you a link that opens the route form already filled in. Nothing is saved until you check it and click Save route.

Sidekick never fills in your secret keys. You type them into the form yourself. If your example contains a real key, replace it with a placeholder such as YOUR_API_KEY before pasting.

Sidekick can also review a route’s security, give you the code to call a route from your theme, tell you how many requests you have used, and explain your Theme Scan findings.

What does each plan include, and what happens at the limit?

Paid plans have unlimited routes and a 14-day free trial, and you are billed through Shopify.

Every request through a route counts, including cached responses. The app warns you at 80% of your monthly limit. At 100%, proxy requests are blocked until the next month starts, and we email you. On Free, delete a route or upgrade to add a third one.

How do I get help?

On the Free plan, use the Contact support button inside the app. Paid plans get live chat in the app. You can always email support@webite.rocks.