Authentication
Proving who a principal is — humans and machines — and managing the tokens that carry that proof. Implements ADR-0010 and ADR-0036. Closes OWASP API2 (Broken Authentication).
1. Human Authentication
| Method | Use | Notes |
|---|---|---|
| OIDC (Auth Code + PKCE) | SaaS + SSO logins | OAuth 2.1 baseline; pluggable external IdP |
| SAML | Enterprise SSO | For IdPs that require it |
| Password | Self-hosted / fallback | argon2id hash; breach-check via HIBP k-anonymity; no composition-rule theater |
| MFA | All human logins | WebAuthn / passkeys preferred (phishing-resistant), TOTP fallback |
| Step-up auth | Sensitive operations | Re-prompt MFA for key rotation, external sharing, admin / role changes, billing |
Passkeys first: WebAuthn removes the password attack surface; passwords remain a hardened fallback. Step-up decouples “logged in” from “allowed to do something dangerous” — a stolen session still cannot rotate keys or exfiltrate via mass external share without re-authentication.
2. Machine Authentication (ADR-0035)
- Workload identity via OIDC (SPIFFE/SPIRE or cloud workload identity): services authenticate with short-lived JWTs issued by the runtime. No long-lived static secrets.
- mTLS between internal services for zero-trust service-to-service calls.
- Scoped API keys for service accounts and developer integrations: hashed with bcrypt/scrypt at rest, never stored plain. Carry explicit scopes (
files:read,files:write,shares:create) and are a strict subset of the principal’s rights. Rotatable with expiry. - API keys carry no interactive privileges (no MFA-gated or admin-destructive actions without step-up) — a leaked key has a deliberately small blast radius.
3. Token & Session Policy (OAuth 2.1 / RFC 9700)
| Control | Policy |
|---|---|
| PKCE | Mandatory for all clients — public and confidential; kills authorization-code interception |
| Grants allowed | Authorization Code + PKCE only — no implicit, no ROPC (both removed in OAuth 2.1) |
| Redirect URIs | Exact string match — no wildcard, no open redirect |
| Access token TTL | 5–15 min for sensitive operations; 30–60 min general |
| Refresh tokens | Rotation + reuse detection — on reuse, invalidate the entire token family and force re-authentication |
| Sender-constraining | DPoP (public clients) or mTLS-bound tokens (confidential clients) for high-assurance operations |
| JWT validation | Verify exp, nbf, aud, iss, signature; reject alg:none; rotate signing keys via JWKS |
| Web sessions | Cookies HttpOnly + Secure + SameSite=Strict; idle and absolute timeout; rotate session on privilege change |
sequenceDiagram
autonumber
participant C as Client
participant GW as Gateway
participant IdP as OIDC IdP
C->>GW: start login
GW->>C: redirect (PKCE code_challenge, exact redirect_uri)
C->>IdP: authenticate + MFA / passkey
IdP-->>C: authorization code
C->>GW: code + code_verifier (PKCE)
GW->>IdP: exchange (verify challenge)
IdP-->>GW: id_token + access (short TTL) + refresh
GW-->>C: session (DPoP-bound, httpOnly cookie)
Note over GW: tenant_id derived from VERIFIED token — set as request-scoped context
:::tip DPoP — Sender-Constraining For high-security operations (admin API, key management), DPoP tokens bind the token to the client’s key pair using a proof-of-possession mechanism (RFC 9449). A stolen DPoP token is useless without the corresponding private key — theft of the bearer token alone is not sufficient to replay the request. :::
:::warning Redirect URI and grant rules Redirect URIs must be exact-matched at the authorization server. PKCE is mandatory — never skip it even for confidential clients. Never accept implicit-flow tokens. Any misconfiguration here is a direct account-takeover path. :::
4. Token Propagation
The gateway authenticates at the edge, derives tenant + principal context from the verified token, and propagates a signed internal auth context over mTLS (ADR-0010). Downstream services re-validate context on every authorization decision — never re-trusting client input downstream.
tenant_id is derived from the verified token before business logic runs. It is never accepted from request parameters or headers provided by the client.
5. External IdP Federation
Enterprise tenants can federate their own OIDC or SAML identity provider. The gateway maps the external identity to a BitVault principal, validates tenant membership, and issues a session with the same security properties as a native login. Per-tenant SSO configuration is isolated; one tenant’s IdP cannot affect another’s.
6. Threats Addressed
| Threat | Control | Residual |
|---|---|---|
| Credential stuffing / brute force | MFA + lockout + breach-password check + rate limiting | Low (human factor) |
| Token theft / replay | Short TTL + rotation + reuse detection + DPoP | Low |
| Code interception | PKCE + exact redirect | Very low |
| Phishing | Passkeys (phishing-resistant) + step-up | Low–medium |
| Leaked API key | Hashed, scoped, rotatable; no interactive privilege | Medium → low with secret scanning |
| Session fixation / XSS | httpOnly + Secure + SameSite=Strict + CSP |
Low |