Skip to main content

Authentication

Scryon supports two authentication mechanisms. They are independent and can be combined.

Every request to /api/** (except /api/health) must carry a valid Firebase ID token:

Authorization: Bearer <Firebase ID token>

Setup​

  1. Create a Firebase project and a service account with the Firebase Authentication Admin role.
  2. Export the service-account JSON.
  3. Set these env vars on the backend:
FIREBASE_PROJECT_ID=scryon-prod
FIREBASE_CLIENT_EMAIL=firebase-adminsdk-xxxx@scryon-prod.iam.gserviceaccount.com
FIREBASE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n"

When FIREBASE_PROJECT_ID alone is set, Scryon verifies tokens against the public JWKS. When the service account is also supplied, the Firebase Admin SDK's verifyIdToken is used — slightly slower but better at honouring revocation.

What the server does​

  • Validates the JWT.
  • Extracts uid, email, name.
  • Finds or creates the matching row in users.
  • Attaches a ScryonAuthentication to the security context for the rest of the request.

Errors​

StatuscodeCause
401auth_missingNo Authorization header.
401auth_invalidToken failed signature / expiry / audience check.
403auth_disabledToken valid but the user is disabled in Firebase.

2. API key (internal / dev)​

A shared-secret guard for environments without Firebase. When SCRYON_API_KEY is set, every request must include:

X-Scryon-Api-Key: <key>

API key alone does not establish a user identity — only Firebase does. The API-key guard is intended for non-user endpoints (webhooks, internal probes).

3. Local dev shortcut​

When neither Firebase nor API key is configured, LocalDevUserFilter attaches a fixed local-dev user to every request. This filter is registered only when FIREBASE_PROJECT_ID is empty.

Never deploy with both Firebase off and API key off. That configuration is intended exclusively for local dev.

Ownership enforcement​

Every domain controller checks the authenticated user against the resource being accessed:

  • GET /api/calls/{id} → 404 if the call belongs to another user (we don't leak existence with 403).
  • GET /api/calls/{id}/transcript → same.
  • DELETE /api/calls/{id} → same.
  • GET /api/actions → only returns the user's own action items.

There is no concept of teams or shared workspaces yet.

Token lifecycle (mobile clients)​

The Android client refreshes the Firebase ID token automatically. Long-lived sessions on mobile are fine — tokens auto-rotate on a 1-hour cadence. If you see 401s after a successful login, force-refresh:

firebaseAuth.currentUser?.getIdToken(true)

Multi-environment auth​

For Cloud Run / Railway / Fly deployments where build artifacts move across environments, prefer separate Firebase projects per environment (scryon-dev, scryon-staging, scryon-prod). Tokens issued by one project will be rejected by another, which is the safe default.