Files
DevRunbook-Public/adr/ADR-006-better-auth-adapter-boundary.md
T
DevRunbook release export cfd2804e27
Managed validation / full (push) Successful in 3m18s
Publish DevRunbook source
2026-09-03 04:09:17 +02:00

45 lines
3.8 KiB
Markdown

# ADR-006 — Application-owned Better Auth persistence adapter
## Status
Accepted for Milestone 0 on 2026-07-27.
## Context
DevRunbook requires database-backed revocable sessions, hashed bearer tokens at rest, simultaneous 12-hour idle and 30-day absolute expiry, explicit revocation records, operator-issued password-reset links, first-run ownership in one transaction, and application-owned workspace authorization.
Better Auth 1.6.25 is compatible with Next.js 16 and Drizzle/PostgreSQL, but its stock database model stores the session bearer value directly, removes sessions during ordinary revocation, stores credential passwords on an account row, and exposes one rolling session expiry. Applying its generated schema unchanged would conflict with the security and lifecycle contracts in documents 26, 31, and the reference database model.
## Decision
Keep Better Auth 1.6.25 as the authentication protocol, credential-workflow, cookie, origin/CSRF, and request-handler engine. DevRunbook owns:
- Drizzle schema and migrations;
- a Better Auth custom database adapter that transforms high-entropy session tokens before persistence;
- idle, absolute-expiry, revocation, and disabled-user checks;
- first-run ownership and package import transaction;
- invitations, operator reset tokens, audit events, and session revocation use cases;
- a versioned envelope around the selected Better Auth-compatible scrypt parameters, plus transparent successful-login migration from Better Auth 1.6's unversioned `salt:key` format;
- every instance-role and workspace authorization decision.
The stock `drizzleAdapter()` and Better Auth migration command are not production migration paths. Better Auth schema generation may be used only as a compatibility check. Cookie caching remains disabled so revocation is visible on the next request. Next.js proxy logic may improve routing but is never an authorization boundary.
## Consequences
- Authentication integration is more work than the stock adapter, but no raw session bearer value is retained in PostgreSQL and the product contracts remain enforceable.
- New password hashes record their algorithm version and work factors. A future parameter change must retain verification for the preceding envelope version and mark it for successful-login rehash; malformed or unknown formats fail closed.
- Adapter conformance, token-at-rest, expiry, revocation, CSRF, cookie, first-run concurrency, reset replay, and cross-workspace tests become mandatory Milestone 0 evidence.
- If Better Auth's adapter API cannot support these transformations without security or correctness gaps, implementation must stop for a blocker-level replacement ADR rather than silently weakening the requirements.
## Evidence
Implemented conformance evidence in Milestone 0 includes generic credential failures, secure cookie attributes, same-origin mutation rejection, HMAC-only session persistence, simultaneous idle/absolute expiry, disabled-user denial, logout-to-`revoked_at` mapping, versioned scrypt hashes and successful-login legacy rehash. The credential account is a virtual adapter model over `users.password_hash`; the only compatibility columns added to `users` are `email_verified` and nullable `image`.
Live PostgreSQL adapter evidence remains required because the current workstation has no Docker-compatible runtime or standalone PostgreSQL service.
- Better Auth custom adapter API: <https://better-auth.com/docs/guides/create-a-db-adapter>
- Better Auth custom password hashing: <https://better-auth.com/docs/authentication/email-password#password>
- Better Auth database schema: <https://better-auth.com/docs/concepts/database>
- Better Auth session management: <https://better-auth.com/docs/concepts/session-management>
- Better Auth security model: <https://better-auth.com/docs/reference/security>