Hoppa till huvudinnehåll
Petanque Life

Sys Authentication & Access Control

F21.01 9 features

I korthet

The hardened entry door to the sys console: OAuth-only login through Microsoft or Google, a strict email allowlist, mandatory WebAuthn as second factor, four scoped sys roles, 60-minute sliding sessions with an 8-hour hard ceiling, and a 5-minute fresh-auth gate guarding every sensitive mutation.

Så fungerar det

There is no password path and no OTP path. An operator hits `/auth/sys/login/start`, picks Microsoft or Google, and the API verifies the returned token against the provider's JWKS. The email claim is then matched against `SYS_ADMIN_EMAILS`; the allowlist entry can pin a specific provider per email when an operator must use a particular identity (`alice@example.com:google`).

A successful OAuth round-trip mints only a 2-minute pending JWT, never a usable sys-JWT. The operator must then complete a WebAuthn assertion via `/auth/sys/webauthn/authenticate/{start,complete}`; only then is the full sys-JWT issued. First-time onboarding flows through `/auth/sys/webauthn/register-onboard/*` so a brand-new operator can register their passkey without already having one.

The sys-JWT is ES512-signed, namespace-isolated from tenant JWTs, and slides activity for 60 minutes up to a hard 8-hour ceiling per login (the `hard_exp` claim is immutable across reauth). Roles are `sys_support`, `sys_engineer`, `sys_finance`, and `sys_security`, granted via `POST /auth/sys/users/{email}/roles`; an operator may hold several, self-grant is blocked, and every grant requires fresh-auth. The fresh-auth gate uses `@requires_fresh_auth(300)` to return `401 fresh_auth_required` with a `reauth_url`; the FreshAuthGate component in the console resolves it transparently via WebAuthn so the operator only sees a brief biometric prompt.

Force-logout of any sys session lives in the Operator sessions panel and is `sys_security`-only with mandatory reason. The break-glass endpoint is present as a 501 shell today and ships its full two-admin-confirm + 15-minute cap flow alongside the deploy hardening track.

Centrala funktioner

  • OAuth-only login via Microsoft or Google with per-email provider pinning
  • Mandatory WebAuthn second factor before sys-JWT is minted
  • 60-minute sliding session with 8-hour immutable hard ceiling
  • Fresh-auth gate returning 401 with `reauth_url`, resolved transparently via passkey
  • Four sys roles enforced server-side; self-grant blocked; combinations allowed
  • Operator sessions panel with reason-required force-logout (`sys_security`)
  • Break-glass endpoint shell ready for sealed-envelope YubiKey + two-admin ceremony

I praktiken

A new sys engineer is added to `SYS_ADMIN_EMAILS` and emailed an onboarding link. She visits `sys.petanque.life`, picks Google, completes the corporate SSO flow, and is held on a `/auth/sys/webauthn/register-onboard` page. She taps her YubiKey to register a passkey; the API now mints her first real sys-JWT.

Two days later she opens the User Directory to grant a colleague the `sys_engineer` role. The endpoint replies `401 fresh_auth_required`; the FreshAuthGate pops a passkey prompt, she touches her key, and the grant submits. Her first attempt to grant herself `sys_security` is rejected by the self-grant guard, and she opens a ticket asking another operator to do it instead.

Features i detta subsystem

9
ID Status Funktioner
F21.01.01 Levererad Microsoft OAuth or Google OAuth — no password, no OTP. Each provider is verified against its own JWKS; the token's email claim must match the allowlist (F21.01.02) regardless of provider. Work-Google accounts and Petanque Life Azure AD accounts both accepted so operators can pick the provider their device already has. ✅ PL-T121
F21.01.02 Levererad Email allowlist (SYS_ADMIN_EMAILS setting) — even with a valid Microsoft or Google token, off-allowlist emails are rejected at auth time. The allowlist entry may optionally pin the allowed provider per email (alice@example.com:google) when an operator must use a specific identity. Implemented (PL-T120)
F21.01.03 Levererad Mandatory WebAuthn/passkey as second factor — OAuth mints only a 2-min pending JWT; the full sys-JWT is only issued after a verified WebAuthn assertion. First passkey onboarded via /webauthn/register-onboard/*. Implemented (PL-T121)
F21.01.04 Levererad Four sys sub-roles: sys_support, sys_engineer, sys_finance, sys_security. A user may hold several. Capability matrix enforced server-side via existing ACC-003 deny-by-default framework. Self-grant blocked. Implemented (PL-T121)
F21.01.05 Levererad Session TTL 60 min sliding. Activity renews up to a hard ceiling of 8 h per login. hard_exp is immutable across reauth. Implemented (PL-T121)
F21.01.06 Levererad Fresh-auth gate (@requires_fresh_auth(300)) — returns 401 fresh_auth_required with a reauth_url. Frontend FreshAuthGate resolves transparently via WebAuthn. Gated endpoints: role changes, force-logout. Impersonation / refund / secret-rotation land in F21.02 / F21.07 / F21.17. Implemented (PL-T121)
F21.01.07 Levererad Force-logout any sys session from the Operator sessions panel (sys_security only). Reason is required and audited. Implemented (PL-T121)
F21.01.08 Levererad Break-glass account procedure documented — sealed envelope with YubiKey + runbook. Endpoint shell present (/auth/sys/break-glass returns 501 today). Full flow ships with PL-T138. ✅ PL-T122
F21.01.09 Levererad API-token-vy i /settings/api-token — operatören kan visa, kopiera och få curl/httpie/python-snippets för sin egen sys-JWT. REVEAL-prompt + 30 s auto-mask + audit-event sys.token.viewed. Inga nya tokens utfärdas — samma JWT som redan finns i AsyncStorage. ✅ PL-T317