Superseded by 0087: identity is a driver package
and enterprise sign-in moves to Pro; decisions 2 to 4, 7 and 8 carry forward there.
Context
Identity is the most sensitive service and is a candidate to isolate from the start. Products differ in how people sign in, so the framework cannot hard-code one method. Authorization already has a deferral: 0011 defers OpenFGA, SpiceDB and Cedar in favour of an in-house check shaped likecheck(subject, relation, object). This ADR uses
that shape and does not adopt any of those engines. 0010 records how
services are structured; where the identity service sits in the backend layout follows the separate backend decision (TODO).
Decision
- Identity is one service built on Better Auth. It owns users, sessions and credentials; no other service reads its tables (0014).
- Sign-in methods are configuration, per product: magic link, social, password, passkeys, phone and username. A product enables only the methods it lists.
- On mobile the session token is stored in SecureStore. It is never stored in plain app storage.
- Authorization is role-based behind
check(subject, relation, object). Callers use onlycheck; roles are an implementation detail. The shape is Zanzibar-like so a deferred engine can replace it later without caller changes. OpenFGA, SpiceDB and Cedar stay deferred. - Three kinds of non-session credential: personal access tokens (a person’s), tenant service tokens (a tenant’s machine access), and OAuth apps (third parties acting for a user). Tokens are shown once, stored hashed, scoped and revocable.
- SSO is configuration and comes later; it is not built now.
- Operator endpoints are audited: each call publishes an audit event (0047), and a call whose event cannot be recorded is refused.
- Changes under this service need a blocking security review.
Consequences
- A product turns a sign-in method on or off without code changes.
- OAuth apps now means the scope model and consent flow must be designed early (TODO).
- Better Auth becomes a dependency whose upgrades the identity service owns.
Enforcement
Planned — a test thatcheck() is the only authorization entry point other members import, a token-storage test (hashed at rest), and the security-tenancy-reviewer agent on every change under the identity service. Nothing is implemented yet.