Skip to content

Authentication & Accounts

Category: Quality Attributes · Areas: api, data, ui

Description

Category

quality-attribute

Areas

api, data, ui

Boundary

This concern owns the authentication & account product surface — that an account/multi-tenant product can actually be signed into and is scoped to its principals, plus session-token semantics (issuance, rotation, revocation). It is composable and does NOT fill a slot; it defers the backend to the auth-provider slot (default auth-local-sessions).

For the family ownership table (auth / authorization-model / multi-tenancy / security-owasp, plus the admin-console and unity-catalog neighbors) see README-auth-family.md.

auth owns the one thing the rest of the family does not state: an account/tenant product is not done until a real principal can sign up, sign in, and act only within their authorized scope.

Components

  • Onboarding: a working signup that bootstraps the account/tenant and its first owner — not a pre-seeded-only system.
  • Session lifecycle: login, logout, and server-side sessions.
  • Authorization (RBAC): roles appropriate to the product (e.g. owner/admin/member) plus, for multi-tenant products, a global/platform-admin; enforced server-side, never UI-only.
  • Isolation through the principal: every data access and mutation is scoped by the authenticated principal’s account/tenant — a cross-account id is unreachable, not merely unlinked in the UI.
  • Swappable backend: all of the above sit behind the auth-provider slot interface so the provider can change with no call-site rewrite.

Constraints

A real, usable auth surface — not a stub or a seam-only abstraction

  • Signup, login, logout, and sessions must actually work end-to-end against the running system. A provider interface with no usable signup/login flow does not satisfy this concern.
  • Onboarding provisions the account/tenant and its owner principal in one flow; the product is reachable by a brand-new user, not only by seeded data.

Authorization and isolation are enforced server-side, through the principal

  • Roles gate actions on the server (return forbidden on denial); hiding a button is not authorization.
  • Every read and write is scoped by the authenticated principal’s account/tenant. Tenant isolation is a property of the principal, not of careful query-writing.

The backend is swappable; external IdPs are deferred, never hardcoded

  • The auth backend is selected via the auth-provider slot. The shipped default (auth-local-sessions) is a real working local backend. An external IdP (Auth0/OIDC, Clerk, …) is a different slot filler, swapped in by config with no call-site change — its identity provider is never hardcoded across the app, and a deferred live integration is recorded, not faked as “done”.

Drift Signals (anti-patterns to reject in review)

  • A multi-tenant / account product with no signup, login, or sessions (data silently single-tenant or open) → the auth surface is missing
  • Roles checked only in the UI (buttons hidden) with the server still accepting the action → authorization not enforced
  • Tenant scoping done ad hoc per query instead of through the authenticated principal → isolation will leak; bind scope to the principal
  • An AuthProvider/identity interface with no usable signup/login flow behind it → seam-only; build the real local default
  • A specific IdP (e.g. Auth0) referenced throughout call sites → not swappable; contain it to the auth-provider slot filler

When to use

Account-based / multi-tenant products — anything with users, accounts, tenants, orgs, sign-in/session semantics, roles, or principal-scoped data or actions. High autonomy auto-selects this concern for such products (see workflows/references/concern-resolution.md). Do not select it for anonymous public sites, libraries, single-user local CLIs, or machine-only internal APIs unless user/tenant principals are explicit. Compose with the auth-provider slot (backend) and security-owasp (hardening).

Artifact Impact

Selecting this concern requires these artifacts to change (a selected concern absent from them is drift):

  • FEAT: signup/login/logout + session lifecycle as a real product surface
  • TD: server-side RBAC and principal-scoped isolation behind the swappable auth-provider slot
  • DATA_DESIGN: principals/accounts (tenant) and session storage
  • ADR: auth-provider filler choice (local sessions now, external IdP later) + role model

ADR References

Projects record an ADR when choosing or swapping the auth-provider filler (e.g. local sessions now, Auth0/OIDC later) and when defining the role model.

Practices by activity

Agents working in any of these activities inherit the practices below via the bead’s context digest.

These practices realize the auth concern: a real, usable authentication & account surface, with authorization and isolation enforced through the authenticated principal, and the backend behind the auth-provider slot. For the family ownership table (and what security-owasp, authorization-model, multi-tenancy, and the auth-provider slot own instead of auth) see README-auth-family.md.

Design

  • Identify the principal model: individual users, and — for multi-tenant products — the account/tenant they belong to and the role they hold.
  • Define the role model and the capability each role grants (e.g. member → read; admin → +write/act; owner → +manage; platform/global-admin → cross-tenant). Record it (an ADR or an authz capability table).
  • Decide the auth-provider filler (default auth-local-sessions); record any deferred external IdP (Auth0/OIDC) as a slot swap, not a rewrite.

Implementation

  • Onboarding: signup creates the account/tenant and its owner principal, then establishes a session — a brand-new user can reach the product.
  • Sessions: login / logout with server-side sessions; protected surfaces redirect unauthenticated requests to login.
  • RBAC: resolve the principal once per request; gate every protected action server-side by capability; return forbidden (not a silent no-op, not a hidden button) on denial.
  • Isolation: derive the account/tenant scope from the authenticated principal and apply it to every read and write; a cross-account identifier must be unreachable.
  • Swappable backend: all calls go through the auth-provider interface; selecting a different filler (e.g. an external IdP) is config, not a call-site change; vendor/IdP names are contained to the filler.

Verification (composes with the verification concern)

  • The auth surface is exercised against the running system: a real signup → login → authorized action → logout, observed (not asserted).
  • At least one authorization-denied path is exercised (a role/tenant that must NOT be able to act is refused server-side).
  • When an admin-console is present, the primary operator workflow e2e starts by signing in through the UI (see admin-console practices).

Quality Gates

  • A new principal can sign up (provisioning the account/tenant + owner), log in, and log out against the running system — observed.
  • A protected action is refused for an unauthorized role/tenant, server-side.
  • Cross-account/tenant data is unreachable for a principal scoped elsewhere.
  • The auth backend is reached only through the auth-provider interface; the default local filler works; any external IdP is a recorded, swappable deferral — never hardcoded across call sites, never a stub passed off as done.