# Authentication and security design ## Threat posture The service is private and self-hosted but must assume: - the reverse-proxy endpoint may become internet reachable; - an authenticated low-privilege account can be malicious; - imported Markdown and files are untrusted; - database or backup theft is possible; - API tokens can leak; - container compromise must not automatically expose the host. The complete threat register is in `docs/26-threat-model.md`. ## First-run owner setup First-run setup is intentionally available without a separate installation code. The endpoint remains a tightly bounded one-time operation: 1. Expose only that setup is required. 2. Require the new workspace and owner credentials over the setup form. 3. Protect the mutation with CSRF validation and a setup-specific rate limit. 4. Atomically create installation, workspace, owner and settings. 5. Permanently disable first-run registration after successful completion. 6. Audit successful completion without recording passwords or tokens. The setup endpoint must not be exposed through an internet-facing reverse proxy before owner setup is complete. Complete setup over the trusted LAN or HTTPS endpoint, then configure the reverse proxy and create the first backup. ## Password authentication Use ASP.NET Core Identity or an equivalent reviewed implementation. Policy: - minimum 12 characters by default; - allow password-manager generated long passphrases; - maximum input bound high enough for passphrases; - no arbitrary composition rules; - check against a small bundled common-password denylist where feasible without an outbound service; - adaptive, versioned password hashing; - transparent rehash on successful login when policy changes; - generic authentication failure; - exponential/threshold lockout; - session/security stamp invalidation after password reset or account disable. ## Operator-issued recovery No email provider is required. 1. Administrator or local operator issues a single-use recovery token. 2. Token has at least 256 bits of entropy, a short expiry and one-use state. 3. Store only a verifier. 4. Deliver through an operator-visible channel. 5. Prefer a URL fragment so the raw token never enters access logs: `https://knowledge.example/#/recover/`. 6. Client posts the token body to the API. 7. Successful reset consumes the token and invalidates sessions. 8. Record safe audit metadata. For the final administrator, provide a documented container operator command that creates a recovery token without database surgery. ## Browser sessions - Secure cookie in HTTPS production. - HttpOnly. - SameSite=Lax or stricter based on tested flows. - Bounded idle and absolute lifetime. - Session rotation after authentication/privilege change. - Anti-forgery token on all cookie-authenticated mutations. - No auth tokens in localStorage. - Logout invalidates server-side session/security state where implemented. - Concurrent session view/revocation is desirable in M1. ## Authorization Authorization is workspace- and resource-aware. - Reader: view/search permitted content. - Editor: reader plus content/project creation and editing. - Administrator: editor plus users, imports, backup, retention, audit and service accounts. - Service account: scopes plus explicitly assigned workspace/content access; no role inheritance. Rules are enforced in Application use cases and query specifications. Endpoint attributes alone are insufficient. Tests cover: - unauthenticated access; - role escalation; - object-ID substitution; - cross-workspace access even though UI exposes one workspace; - trashed/private content; - attachment and revision access; - project context aggregation; - disabled users and revoked tokens. ## Service-account tokens Format contains a non-secret public ID/prefix and a random secret. Store only a verifier. - Show once. - Optional expiry. - Multiple independently revocable tokens per account. - Named purpose and last-used time. - Explicit scopes. - Immediate revocation. - Constant-time verification. - Rate limit failed token authentication. - Never accept token in query string. - Never log the authorization header. A database compromise should not make offline token recovery feasible because secrets are uniform random 256-bit values. ## CSRF, CORS and origins - Browser API is same-origin in production. - CORS disabled unless a specific trusted integration requires it. - Anti-forgery for cookie mutation. - Bearer-token calls do not use cookies. - Validate configured public/base URL. - Proxy headers accepted only from configured trusted proxy networks. - Host filtering enabled. ## Content security Recommended production headers: - Content-Security-Policy with no unsafe inline script; - `frame-ancestors 'none'` unless explicitly required; - `object-src 'none'`; - `base-uri 'self'`; - `form-action 'self'`; - HSTS at reverse proxy after HTTPS validation; - X-Content-Type-Options; - Referrer-Policy; - Permissions-Policy. Rendered Markdown disallows raw HTML and unsafe URLs. Mermaid uses strict mode. Uploads are not served as executable same-origin content. ## Secrets and encryption - Secrets enter through mounted secret files or environment variables. - ASP.NET data-protection keys persist outside the read-only root filesystem. - Production data-protection keys should be protected with an operator-managed secret where supported. - Backup encryption is operator-configurable and must not rely on a key stored only inside the backup. - API tokens, passwords and bootstrap/recovery secrets are never recoverable from the DB. - Do not pretend application-level encryption protects against a fully compromised running application; document the threat boundary. ## Logging and privacy Never log: - passwords; - raw tokens; - cookies/session IDs; - CSRF tokens; - page bodies by default; - attachment content; - full recovery/bootstrap links; - database connection strings. Use safe IDs, correlation IDs and redacted structured properties. Audit retention and diagnostic-log retention are separate. ## Rate limits and abuse controls At minimum isolate policies for: - setup/login/recovery; - failed bearer authentication; - global search; - upload; - import/export/backup; - expensive project-context requests. Return a generic response that does not confirm account/content existence. ## Security verification Release requires: - dependency vulnerability scan; - secret scan; - container scan; - authorization matrix tests; - CSRF tests; - XSS corpus; - malicious upload/path corpus; - session/token lifecycle tests; - security header test; - non-root/read-only container evidence; - independent security review.