Repository navigation
Authenticate Cloudflare-to-origin requests independently of end-user auth #87
Description
Goal
Establish an explicit Cloudflare-edge → Zed-origin service-authentication boundary that is independent of the end user's registry/session/provider credential. Origins should be able to prove that a request came through the reviewed Zed edge path even if the origin hostname/address becomes reachable directly.
This complements, but does not replace, end-user authorization and the signed authenticated-fallback capability work in #74/#80.
Required properties
Use a short-lived asymmetric or otherwise least-privilege service-auth scheme that binds at least:
- issuer / edge identity;
- exact origin audience;
- HTTP method;
- canonical path (and canonical query policy where applicable);
- request timestamp / bounded validity window;
- unique request or replay identifier;
- body digest for requests with a body;
- OriginSet/config generation or deployment audience where needed to prevent cross-environment replay.
The design may use signed request headers/JWT-style proof, Cloudflare service tokens/mTLS where deployment adapters support them, or a composed scheme, but the wire contract and replay semantics must be explicit and testable.
Separation from user credentials
- Service authentication proves edge provenance, not user/package authority.
- Existing user bearer/session auth is still evaluated independently.
- Never wrap or serialize the user's GitHub PAT, npm token, Cargo credential, SSH key, Supabase/Neon credential, or Shared Auth secret inside the edge-service proof.
- A valid edge proof cannot authorize a private package by itself.
- An invalid/missing edge proof must not be repaired by accepting a valid end-user token on an origin route configured as edge-only.
Origin behavior
- Verify service proof before expensive DB/provider work on edge-only ingress.
- Reject wrong audience/origin, stale/future timestamps, replayed request ids, body-digest mismatch, unsupported algorithm/key id, and canonicalization mismatch.
- Keep direct health/compatibility probes explicitly classified; if they are intentionally public, do not accidentally grant them application-route authority.
- Preserve the ability to run local/test adapters with a separate explicit test policy rather than silently disabling verification.
Rotation / availability
Key discovery/rotation must support overlap and bounded caching. Unknown key ids fail closed; issuer/JWK outage behavior must be tested separately from ordinary user auth availability.
Deployment adapters
Prove the same semantic service-auth boundary for at least:
- AWS/GCP Kubernetes ingress;
- GCP Cloud Run;
- Scintilla;
- BeamScale where the hosted runtime exposes the required request-verification primitive.
Unsupported adapter behavior must be explicit rather than silently unauthenticated.
Tests
- valid signed GET and body-bearing write;
- wrong origin audience;
- method/path/query substitution;
- body tampering;
- expired/not-yet-valid proof;
- replay;
- unknown/retired key;
- user token valid but edge proof invalid;
- edge proof valid but user lacks package authority;
- direct-origin request cannot impersonate Cloudflare;
- key rotation overlap;
- redaction: no proof/user/provider credential appears in ordinary logs.
Activity