Skip to content
Docs

Command palette

Jump to a page or view, or find a todo by name.

Changelog

Server reads the session from the cookie cache

The repository's architectural decision, rationale and consequences.

Markdown

Status: accepted · Date: 2026-11-09 · Amends: ADR-0003

Enforcement: packages/api/src/platform/rpc/session-authority.test.ts, packages/auth/src/auth-round-trips.test.ts, apps/web/src/routes/api/session-revocation.test.ts.

Every signed-in request previously read the Session and User from Postgres. A mobile scoped call read it twice. The files gateway read it twice and then read membership. Issue #189 and PRs #192–#194 reduced the browser presentation read; the owner accepted a 60 second revocation window for ordinary data access to remove the remaining serial session read.

Decision

  1. SSR, oRPC and the files gateway read the request session from Better Auth's signed compact cookie snapshot, at most 60 seconds old, or from Postgres on a miss.
  2. Procedures that create, reveal or redirect credentials or standing channels, change account control, administer Users, touch billing or push, or approve a pending agent tool call that lets a run continue (agentTools.resolve) read the database session. Resolving a stored proposal (proposals.resolve) is a one-shot data write, like the manual path, and uses the request session. markAuthoritative and session-authority.test.ts classify every procedure. Admin and sensitive Better Auth endpoints remain authoritative.
  3. The membership reader checks member on every request. RLS checks app.org_id() on every tenant statement.
  4. The Better Auth handler strips the snapshot from every endpoint except the presentation GET /get-session.
  5. The cookie integration forwards Set-Cookie on a miss. A hit does not re-issue the snapshot.
  6. The mobile scope header is compared with the request session. Authoritative procedures compare it again with the database read.

Consequences

Session reads records the revocation behavior. A copied cookie can continue to access ordinary data for at most 60 seconds. An SSE request keeps the identity read at its start. Bump session.cookieCache.version when fields used by the server change. A mobile RPC response does not store the re-issued cookie, so subsequent requests can miss again. Local measurements are recorded in the measurement report.

Alternatives

  • The status quo retains a serial database round trip on every request.
  • KV secondaryStorage is eventually consistent, has no atomic operations, and moves sessions out of Postgres.
  • Isolate-local memory has no cross-isolate invalidation.
  • A shorter maxAge reduces the window but increases misses.
Edit on GitHubDocumentation is in English.
Cookie settings
We use essential cookies to make our app work. With your consent, we also use optional cookies to improve your experience.

Read our Cookie Policy and Privacy Policy.