API Authentication

All API requests must carry a valid bearer token. BitVault uses OAuth 2.1 with PKCE (ADR-0010) for interactive flows and scoped API tokens for programmatic access.

Bearer Token

Authorization: Bearer <access_token>

Every API endpoint validates the token on every request: signature, expiry (exp), audience (aud), issuer (iss), and tenant claim. Validated tokens are cached in Redis for the hot path (configurable TTL, default 30 s) to avoid repeated JWKS fetches under load.

:::warning Token lifetime Access tokens are short-lived (default: 15 minutes). Use the refresh token endpoint to obtain a new access token before expiry. API tokens have configurable expiry and should be rotated on a schedule appropriate to their privilege level. :::

OAuth 2.1 Interactive Flow

For web and mobile clients:

  1. Authorization Code + PKCE: client generates code_verifier + code_challenge.
  2. Redirect to authorization endpoint with response_type=code&code_challenge=....
  3. User authenticates; authorization server redirects back with code.
  4. Exchange code + code_verifier for access token + refresh token.
  5. Refresh token rotation: every token refresh issues a new refresh token; the old one is invalidated. Replay of a rotated refresh token revokes the entire session.

API Tokens

Long-lived, scoped tokens for CLI and automation use. Created via:

POST /v1/api-tokens
Property Description
Scope One or more permission scopes (e.g. files:read, files:write, admin)
Expiry Configurable; required (no indefinite tokens)
Name Human-readable label for auditing

API tokens are passed as Authorization: Bearer <api_token>. They resolve to the owning user’s identity and tenant at validation time.

Example Request

curl -H "Authorization: Bearer $TOKEN" \
     https://api.bitvault.example/v1/files

Rate Limit Headers

Every response includes rate-limit headers:

Header Value
X-RateLimit-Limit Maximum requests allowed in the current window
X-RateLimit-Remaining Requests remaining in the current window
X-RateLimit-Reset Unix timestamp when the window resets

Rate limits are enforced per-token (or per-IP for unauthenticated endpoints) and stored in Redis. A 429 Too Many Requests response is returned when the limit is exceeded; the Retry-After header indicates how long to wait.

Token Validation Summary

Check Enforcement
Signature JWKS from issuer; cached
exp Must be in the future
aud Must match the configured API audience
iss Must match the configured issuer
tenant claim Must match the resource’s tenant (enforced at RLS layer)
Token revocation Redis blocklist for explicitly revoked tokens