0010: Standard OIDC, stateless bearer tokens ============================================ :Status: Accepted :Date: 2026-10-19 Context ------- The deployment's existing SSO and RBAC had to be preserved, and the specification forbade inventing a custom JWT validator. Decision -------- The backend is an OIDC resource server: it validates RS256 tokens with PyJWT against the provider's discovery document and JWKS (issuer, audience ``adr_viewer`` by default, and a configurable roles claim path). The SPA is a public client using Authorization Code + PKCE through ``oidc-client-ts`` and keeps tokens in memory. Permissions (``read``, ``operate``) map from IdP roles in ``catalog.yaml``; reviewer eligibility comes from the approval policy, never from read permission. Consequences ------------ * No user table and no server session. * An unreachable IdP answers 503, not 401, and never stops startup: discovery is lazy. * A full page reload signs the user out; that is the price of never putting a token in browser storage. * RP-initiated logout is not implemented.