Skip to content

Security invariants

These rules are enforced by the Central Auth Gateway. Platform integrations must respect them; bypassing them in the BFF creates security holes even if Central itself remains correct.

Identity and tokens

  • ZITADEL owns credentials, MFA/passkeys, and OIDC tokens.
  • Platforms never receive ZITADEL ID, access, or refresh tokens from Central.
  • PKCE verifiers and nonces never leave Central (stored hashed / encrypted; not returned on exchange).
  • Externally supplied ID tokens are rejected; only the central code exchange path establishes identity for login.
  • Tokens and handoff codes must never be logged.

Handoff

  • Codes are prefixed handoff_, stored as SHA-256 only, short-lived (AUTH_HANDOFF_TTL_SECONDS, 30–300s), platform-bound, and atomically single-use.
  • Exchange requires platform Basic auth (client_id + scrypt-verified secret) for an active platform.
  • A code belonging to another platform cannot be exchanged (404).
  • The pending gatewayToken is AES-256-GCM encrypted at rest and revealed only after successful exchange.

Gateway session

  • Opaque random token; only the hash is stored.
  • Cookie: HttpOnly, SameSite=Lax, Path=/, Secure in production; name from AUTH_SESSION_COOKIE_NAME (default iesf_auth_session).
  • TTL from AUTH_SESSION_TTL_SECONDS (default 43200).
  • Inactive / soft-deleted users cannot authenticate a session.
  • Cookie-authenticated writes require an allowlisted Origin.

Platform registry

  • Callback URL, return URL roots, and onboarding mode come from the server-side registry, not from untrusted query overrides.
  • onboardingMode on start is assertion-only.
  • Active platforms must have callback, at least one return URL root, and credentials.
  • Client secrets are high-entropy, returned once, stored hashed.
  • Soft deactivation preserves memberships, onboarding values, and audit history.

Authorization

  • User IDs are never taken from profile/account request bodies for identity.
  • Platform ownership for admin/schema routes is derived from verified token claims/scopes (or platforms:admin), not from trusting a body/path platform key alone.
  • Passwords go only to ZITADEL and are redacted from logs.
  • Normal account deletion is reversible local soft delete plus ZITADEL deactivation/revocation attempt; local profile and audit data remain.

Onboarding integrity

  • Completion is always recalculated server-side from active required definitions and current values.
  • Resume ignores client completion assertions.
  • Historical onboarding values remain when definitions are archived.
  • Schema definitions cannot carry arbitrary executable / HTML payloads; uiConfig is declarative.

Operational

  • Application instances are stateless; auth state lives in PostgreSQL.
  • Do not connect to or migrate ZITADEL’s database from this service.
  • Generate API clients from /openapi.json; treat Swagger examples as illustrative and verify against runtime for security-sensitive fields.