API Authentication
Authenticated requests use one of two edge-authenticated paths.
In plain language, there are two ways to prove a request is allowed to call the API:
X-Tokenplus HMAC device headers for mobile clientsAuthorization: Bearer <firebase-id-token>for standard JWT clients
The two paths are mutually exclusive per request.
Mobile Path: X-Token + HMAC
Mobile clients send a Firebase ID token in X-Token plus device-bound HMAC headers. The Envoy WASM filter validates the HMAC, and Envoy's SecurityPolicy validates the Firebase JWT from the same header.
The practical meaning is: one part identifies the user, and one part proves the request was signed the way the mobile path expects.
| Header | Description | Example |
|---|---|---|
X-Token | Firebase ID token | eyJhbGciOi... |
X-Timestamp | RFC 3339 UTC timestamp | 2025-01-15T12:00:00Z |
X-Signature | Hex-encoded HMAC-SHA256 of "<token>:<timestamp>" | a1b2c3d4... |
X-Device-Info | Device information string | iPhone 15 Pro, iOS 18.1 |
X-Version | App version string | 1.2.0+42 |
X-Device-ID | Optional device identifier recorded by the backend | 550e8400-e29b-41d4-a716-446655440000 |
X-Timezone | Optional client timezone recorded by the backend | Europe/Berlin |
HMAC Signature
The signature is computed as:
signature = hex(HMAC-SHA256(secret, "<X-Token>:<X-Timestamp>"))
The orchestrator does not re-validate the mobile HMAC. It reads trusted X-Firebase-* headers forwarded by Envoy after JWT validation.
JWT Path: Authorization: Bearer
For backend tooling and service-to-service calls, use a standard Bearer token:
Authorization: Bearer <firebase-id-token>
Requests with Authorization: Bearer bypass the HMAC filter entirely. JWT security is handled by Envoy's SecurityPolicy, which validates against Firebase's JWKS endpoint.
If you are building or scripting against the API and you are not the mobile app, this is usually the path you want.
Local And E2E Behavior
- In
localandtest, backend auth middleware injects a default development principal and skips edge-style auth entirely. - In non-production deployed environments, a separate e2e bypass exists via
X-E2E-TokenplusX-E2E-UID/X-E2E-Email/X-E2E-Name. - There is no
CRAWL_AUTH_ALLOW_DEV_TOKENStoggle and nodev:{subject}:{email}:{name}token parser in the current backend.