Skip to content

Security overview

High-level picture of how Sophia protects the API, tenants, and sensitive data.

Auth flow

flowchart LR
  Client[Browser / Bot / Stripe]
  API[Sophia API]
  Firebase[Firebase Auth]
  DB[(MongoDB)]

  Client -->|Bearer ID token| API
  Client -->|Join / session tokens| API
  Client -->|x-internal-token| API
  Client -->|stripe-signature| API

  API --> Firebase
  API --> DB

Security controls

AreaWhat exists
SaaS authFirebase ID token verification; active user + org; suspended org blocked
Rolesadmin and member; admin-only routes for billing, team, some deletes
Candidate accessHashed join tokens; optional password; session header; rate limit on failed passwords
Bot accessShared secret header
Stripe webhooksHMAC signature on raw body
TransportSecure headers, CORS allowlist
InputZod validation on routes
Tokens at restSHA-256 hashes for join, session, and invite tokens
PIIAES-256-GCM for candidate phone; Pino redaction for logs
SecretsGitleaks in CI

Tenant isolation

One shared database. Every tenant query filters on organizationId in repository layers. Auth resolves org from the user record, not from the request body.

Known gaps

  • Only two roles — no fine-grained permissions matrix in middleware
  • No API-wide rate limiting (except candidate password verify)
  • Firebase ID tokens stay valid until expiry after logout or role change
  • Encryption covers candidate phone only, not email or names
  • organizationId / userId are not auto-attached to every log line (only requestId)
  • No compliance certifications encoded in the product

Sophia AI Interview Platform — Internal Documentation