dorfteich/docs/architecture/adr/0007-auth-sessions-oidc-ready.md
Claude Fable 5 0629411966 Add architecture documentation, ADRs, and operations concept
Initial deliverable of the architecture phase: 16 ADRs (stack, CRDT
collaboration, plugin sandbox, import/export, backups, CI/CD), data
model, permission model, real-time collaboration and plugin concepts,
deployment/operations/security documentation, and the milestone roadmap
that the implementation issues are derived from.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 14:36:16 +02:00

62 lines
2.7 KiB
Markdown

# ADR 0007: Cookie sessions, Argon2id, OIDC-ready identity model
- Status: accepted
- Date: 2026-07-04
## Context
Kickoff decisions: self-contained user management (username, e-mail,
password) with mandatory e-mail verification (double opt-in), password
reset, rate limiting, and the option to disable self-registration per
instance. SSO is not in the MVP but the design must allow adding OIDC login
later without schema surgery.
## Decision
### Authentication
- **Server-side sessions** stored in PostgreSQL, referenced by an opaque
`HttpOnly; Secure; SameSite=Lax` cookie. No JWTs for browser sessions
(revocability and simplicity win). Sliding expiration, default 30 days.
- Passwords hashed with **Argon2id** (tuned parameters documented in code).
- **E-mail flows** (verification, password reset) use single-use, expiring,
hashed tokens; mail is sent via SMTP (instance-configured, see setup
wizard) through a mail outbox table with retry.
- **Rate limiting** on signup, login, password reset, and token endpoints:
fixed-window counters in PostgreSQL keyed by IP and by account —
no Redis (ADR 0002).
- Self-registration can be disabled instance-wide
(`instance_settings.registration_mode`: `open` | `closed`). The kickoff
also asked for the option of admin approval as a later hardening step; the
setting is an enum so `approval_required` can be added without migration
pain.
- **Collaboration tokens**: the API issues short-lived (≤ 60 s validity for
connect) signed JWTs solely for the WebSocket handshake with the collab
server (ADR 0003). These are the only JWTs in the system.
### OIDC readiness (not in MVP)
- The identity model separates **account** from **login method**:
`users` (profile, status) and `user_identities`
(`provider` = `password` | future `oidc:<issuer>`, `subject`,
`credential`). Password login is just one identity row.
- E-mail is unique per user and verified; future OIDC linking matches on
verified e-mail or explicit account linking.
## Consequences
- Logout and account deactivation are immediate (session rows deleted).
- No shared secret sprawl: one signing key for collab tokens, rotated via
environment configuration.
- Adding OIDC later means: new identity provider rows, an
authorization-code flow module, and a login button — no changes to
sessions, permissions, or user references.
## Alternatives considered
- **JWT access/refresh tokens in the browser**: harder revocation, XSS
exposure of tokens, no benefit for a same-origin SPA. Rejected.
- **Auth libraries/services (Keycloak, Authentik as mandatory)**: heavy
extra container contradicting easy self-hosting; external IdPs remain
possible later through the OIDC path.