You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
5.3 KiB
92 lines
5.3 KiB
|
5 months ago
|
# Security Policy
|
||
|
|
|
||
|
5 months ago
|
Active is not production-ready until `0.1.0` is tagged and the security checklist in `docs/before_0_1.md` is closed.
|
||
|
5 months ago
|
|
||
|
|
## Reporting
|
||
|
|
|
||
|
|
Do not open public issues for suspected vulnerabilities.
|
||
|
|
|
||
|
|
Use GitHub Security Advisories for this repository when available. If advisories are not available in the current hosting setup, contact the maintainer through a private channel and include:
|
||
|
|
|
||
|
|
- affected module and commit hash;
|
||
|
|
- reproduction steps;
|
||
|
|
- expected impact;
|
||
|
|
- whether credentials, cookies, tokens, permissions or cross-tenant data are involved.
|
||
|
|
|
||
|
|
## Threat Model Summary
|
||
|
|
|
||
|
|
Security-sensitive modules are split by responsibility:
|
||
|
|
|
||
|
|
- `auth` proves identity, manages login flows, CSRF, OAuth state/PKCE binding and session binding.
|
||
|
|
- `sess` owns session continuity, revocation and browser/session synchronization.
|
||
|
|
- `perm` authorizes actions for an authenticated actor and tenant.
|
||
|
|
- `cach` must not leak data across actor, tenant, permission, locale or session scopes.
|
||
|
|
- `stor` must not persist secrets unless an explicit adapter and policy say so.
|
||
|
|
- `logr` must redact sensitive payloads and centralize security diagnostics.
|
||
|
|
|
||
|
5 months ago
|
## Browser And Server Auth Threats
|
||
|
|
|
||
|
|
### Cookie scopes
|
||
|
|
|
||
|
|
- `sess` owns the primary session cookie; `auth` only owns helper cookies for CSRF, flows, device hints or refresh mode when explicitly enabled.
|
||
|
|
- Secret cookies must be `HttpOnly`, `Secure`, path-scoped to `/`, and must not set `Domain` unless a deployment has reviewed subdomain trust.
|
||
|
|
- Same-site browser flows default to strict/lax same-site cookies. Cross-site deployments must opt in deliberately and keep CSRF checks enabled.
|
||
|
|
- JavaScript-readable cookies are only for non-secret hints. Access tokens, refresh tokens, OTPs, passwords and CSRF signing secrets must not be readable by client code.
|
||
|
|
|
||
|
|
### CSRF flow
|
||
|
|
|
||
|
|
- State-changing browser auth routes must require a CSRF token and validate origin/fetch metadata when the hosting framework exposes those headers.
|
||
|
|
- CSRF tokens are issued by `auth`, sent by `arts/auth`, verified server-side, and scoped to the configured flow/window.
|
||
|
|
- Missing, expired, replayed or mismatched CSRF tokens must fail before credential, session or provider state is mutated.
|
||
|
|
|
||
|
|
### Refresh rotation
|
||
|
|
|
||
|
|
- Refresh mode, when enabled, must use opaque tokens stored server-side as hashes.
|
||
|
|
- Rotation is single-use: consuming a refresh token creates a child token, marks the parent consumed and binds the new token to the same family/session.
|
||
|
|
- Reuse outside the configured grace window is treated as replay and must revoke the whole refresh family and the linked session binding.
|
||
|
|
- Database adapters must perform refresh lookup/consume/child creation under a row lock or equivalent transaction boundary.
|
||
|
|
|
||
|
|
### OAuth state and PKCE binding
|
||
|
|
|
||
|
|
- OAuth/OIDC flows must persist `state`, `nonce` and PKCE verifier material server-side in an expiring flow record.
|
||
|
|
- Callback completion must compare the returned state with the stored state and send the stored verifier to the provider token exchange.
|
||
|
|
- Email-based account linking must not happen automatically unless the provider marks the email as verified and the application explicitly opts into that policy.
|
||
|
|
- Provider tokens are not persisted by default; applications that keep them need a separate vault/adapter review.
|
||
|
|
|
||
|
|
### MFA status
|
||
|
|
|
||
|
|
- MFA is not part of the stable `0.1` auth surface. Any future MFA/passkey/WebAuthn work must remain experimental until it has flow storage, replay protection, recovery behavior and regression tests.
|
||
|
|
- `auth` may expose AAL/AMR metadata from authenticated sessions, but `perm` decides whether that assurance is sufficient for an action.
|
||
|
|
|
||
|
|
### Actor and tenant model
|
||
|
|
|
||
|
|
- `actorId` is never globally meaningful without `tenantId`.
|
||
|
|
- Auth credential uniqueness, linked OAuth accounts, session bindings and devices must all be tenant-scoped.
|
||
|
|
- Permission decisions and cache keys must include actor/scope information when an authenticated actor is present.
|
||
|
|
- Login/logout, tenant switch, permission change and session revoke must invalidate actor/permission-scoped caches.
|
||
|
|
|
||
|
5 months ago
|
## Current Guarantees
|
||
|
|
|
||
|
|
- Authentication is server-authoritative; the active client reflects state but does not protect routes by itself.
|
||
|
|
- Session cookies and auth helper cookies use explicit cookie constants.
|
||
|
|
- CSRF tokens are required for state-changing auth endpoints.
|
||
|
|
- OAuth flows store state and PKCE verifier server-side and verify the persisted verifier before callback completion.
|
||
|
|
- Permission client cache keys include scope when actor or explicit scope is present.
|
||
|
|
- Memory adapters are for tests, local development and SSR isolation; they warn when instantiated in production mode.
|
||
|
|
|
||
|
|
## Explicit Non-Guarantees Before 0.1
|
||
|
|
|
||
|
|
- MFA is not part of the stable public auth engine surface.
|
||
|
|
- Production WebAuthn/passkeys are not included.
|
||
|
|
- The OAuth provider catalog is not included.
|
||
|
|
- No module should be treated as audited for regulated production workloads.
|
||
|
|
|
||
|
|
## Security Rules For Changes
|
||
|
|
|
||
|
|
- Never add a public route, cookie name, header name, error code, event name or logger category as an inline string.
|
||
|
|
- Never cache private data without actor/tenant scope.
|
||
|
|
- Never persist access tokens, refresh tokens, OTPs, passwords or CSRF tokens in `stor`.
|
||
|
|
- Never use `localStorage` as the source of truth for authentication.
|
||
|
|
- Add regression tests for every security bug fix.
|
||
|
|
- If a module exports a method in the stable surface, it must work or be removed from the surface.
|