Files
oO/docs/adr/0004-auth-authjs-with-oidc-boundary.md
alvis 7f173f88d3 refactor: architecture revision — modular monolith, auth-commit, event protobuf, privacy-from-day-0
- ADR-0003: modular monolith for Phase 0 with documented extraction triggers
- ADR-0004: Auth.js + OIDC-shaped boundary; dedicated provider when mobile ships
- ADR-0005: protobuf for events, OpenAPI for HTTP, schema-registry CI gate
- New architecture docs: data-model, metrics (magic proxies), privacy (Phase-0 feature)
- Prime directives updated: privacy-as-feature, modular-by-package-deployable-by-stage
- Roadmap revised: Apple OAuth deferred to M1; web push in M1; k3s intermediate; tip-kind-aware UI
- PLAN updated: Phase-0 deletion endpoint, metrics baseline, compose profiles, import-boundary lint
- License decision in README (ARR with OSS plan in Phase 5)
2026-04-13 14:36:11 +00:00

1.7 KiB

ADR-0004: Auth.js for Phase 0, dedicated OIDC provider when mobile ships

Status

Accepted — 2026-04-13

Context

We need Google (and later Apple) sign-in, session management, and JWTs other services can verify. Options considered:

  • Auth.js (NextAuth): a library embedded in the Next.js web app. Fastest to ship. Tight coupling to the web runtime; awkward when a native mobile client also needs tokens.
  • Ory Kratos + Hydra: a standalone, self-hosted identity + OIDC provider. Much more powerful. Operationally heavy for a prototype.
  • Roll our own: not considered.

Mobile apps are Phase 3+. Phase 0 needs the cheapest credible option that does not box us in.

Decision

  • Phase 0: use Auth.js inside the web app. Google provider only (Apple deferred — paid dev account + extra domain setup).
  • Boundary: from day one, the auth module exposes an OIDC-shaped HTTP surface (/me, /logout, JWT verification via public JWKS, /.well-known/openid-configuration stub). Other services verify JWTs against that surface, not against Auth.js internals. This means the day we replace the engine, only one module changes.
  • JWT strategy: short-lived (10 min) access JWT, rotating refresh token in an HttpOnly cookie. JWT contains sub, email, scope, sid.
  • Trigger to migrate to Ory (or equivalent): any of — (a) native mobile shipping, (b) a second client type that can't piggyback on Next.js sessions, (c) multi-tenant requirement.

Consequences

  • Ships in days, not weeks.
  • The OIDC-shaped boundary means the migration is scoped, not scary.
  • Slight duplication early: we maintain OIDC-surface code that Auth.js mostly handles internally. Worth it.