Credential-free edge companion: the customer pastes a Snippet

The customer proxies one path (/llms.txt) to your API with a paste-once Snippet; per-site URL tokens are HMAC-derived from the site id, so no secret is stored.

Security

· Chapter

21

·

3

min read

The answer. When your product must serve a file on the customer's domain and their CMS can't host root files, the tempting design — "connect your Cloudflare account" — means holding a customer API token forever. The credential-free alternative: generate a tiny Worker/Snippet the customer pastes onto their proxied zone once. It intercepts exactly one path and proxies it to a public endpoint on your API; every other request is fetch(request), so a botched install can't take the site down. The endpoint URL carries an opaque per-site token derived as HMAC-SHA256(server_secret, "edge:site:" + siteId), truncated. You never store it — you recompute and compare in constant time. No secret at rest, no blast radius, and the content updates itself on every publish.

The pattern.

// api — derive and verify; nothing stored (rotation = rotate the server secret, globally)
async function hmacHex(secret: string, msg: string) {
  const enc = new TextEncoder();
  const key = await crypto.subtle.importKey("raw", enc.encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
  const sig = await crypto.subtle.sign("HMAC", key, enc.encode(msg));
  return [...new Uint8Array(sig)].map((b) => b.toString(16).padStart(2, "0")).join("");
}
export const siteToken = async (env: Env, siteId: string) =>
  (await hmacHex(env.EDGE_TOKEN_SECRET, `edge:site:${siteId}`)).slice(0, 32);
export function tokensMatch(a: string, b: string) {        // constant-time-ish, no early exit
  if (a.length !== b.length) return false;
  let d = 0; for (let i = 0; i < a.length; i++) d |= a.charCodeAt(i) ^ b.charCodeAt(i);
  return d === 0;
}

// the paste-once Snippet handed to the customer (token baked in)
export default {
  async fetch(request) {
    const url = new URL(request.url);
    if (url.pathname === "/llms.txt")
      return fetch("https://api.example.com/public/edge/<token>/llms.txt", { cf: { cacheTtl: 300 } });
    return fetch(request);
  },
};

The receipt. In our API Worker, shipped 2026-08-03: HarperFlow customers' sites live on a hosted CMS that serves no arbitrary root files, so /llms.txt was impossible for them to host. We hold every published article's title, URL and summary, so we generate the file server-side and let the Snippet proxy it. Install is self-verifying: the API fetches /llms.txt on the customer's own host with an 8-second timeout and looks for a sentinel line; a hand-written llms.txt reads as "not installed", and there is no stored flag to drift. Tokens are 32 hex characters; the edge caches the proxied file for 300 s. Install and fetch counts aren't instrumented — unmeasured.

Watch out.

  • HMAC-from-id means rotation is global; the day one customer needs a revoke is the day you add a per-site secret column.
  • Compare tokens without early exit; a plain string compare leaks timing.
  • Verify by probing the customer's live host for your sentinel, never by trusting a "connected" flag.

Related: mcp-server-as-pages-function-stateless-streamable-http · worker-fetch-own-zone-error-1042