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

# Security Policy
Reorganize docs: move working/audit files to docs/ and add conventions Working documents and audits were spread across the project root, mixing with standard npm/GitHub files (README, CHANGELOG, CONTRIBUTING, SECURITY, BRAND). Moves them under docs/ for a clean root and adds docs/conventions.md as the canonical document for codebase-wide naming and structure rules. Files moved to docs/ (via git mv, history preserved): - audit-1-5.md (current ecosystem audit) - AUDIT_KIMI.md - AUDIT_OPENCODE.md - AUDIT_claude.md (historical audits from prior tools) - before_0_1.md (pre-0.1 release checklist) - buss.md (bus design doc, no longer live) - NEXT_STEPS.md (roadmap) Files staying in root (npm/GitHub convention): - README.md, CHANGELOG.md, CONTRIBUTING.md, SECURITY.md, BRAND.md References updated to point at docs/: - CHANGELOG.md (line 11) - README.md (line 105) - SECURITY.md (line 3) - src/web/routes/active/security/+page.svelte (line 46) docs/conventions.md captures three rules accepted as binding for the codebase: 1. Module identifier — every artifact and lib uses its 4-letter alias (BUSS, CONN, SESS, PERM, TIMR, LOGR, CACH, STOR, FMTS, FEND, ADOM, AAPP, AUTH, LANG, HTTP, SIUM, ERRS) for both string values and constant name prefixes. Drift from this rule (BUS_*, CONNECTION_*, SESSION_*, …) is being closed in the next audit pass. 2. Constant naming — `<MOD>_<CATEGORY>_<NAME>` strictly. No exceptions (no DEFAULT_TIMER_* style). 3. Category vocabulary — fixed list of category tokens (ERR, EVENT, DIAGNOSTIC_EVENTS, METHOD, STATE, STATUS, KIND, REASON, TYPE, MODE, DEFAULT, LIMIT, ID_PREFIX, LOG_CATEGORY, LOG_MSG, ERROR_MSG, ERROR_NAME, CONTEXT_KEY). Ad-hoc categories (AUTO_REAUTH, AUTO_INVALIDATE, BUFFER_POLICY, CHANNEL_STATE) fold into one of these. The document also formalizes the layer rules and ErrCode shape that will be implemented in upcoming commits. svelte-check 1395/0 errors. No code-side regressions; the moves are file-only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
## 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.
## 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.
## 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.

Powered by TurnKey Linux.