Files
certctl/docs/operator
shankar0123 944ce8e710 auth-bundle-2 Phase 12: extend auth-threat-model.md with Bundle 2 sections (OIDC + sessions + back-channel logout + OIDC first-admin + break-glass + 8 Bundle 2 threat sub-sections)
Closes Phase 12 of cowork/auth-bundle-2-prompt.md. The single
canonical operator-facing threat model (one doc per topic per the
docs convention) now covers both Bundle 1 (RBAC) AND Bundle 2 (OIDC
+ sessions + back-channel logout + OIDC first-admin + break-glass)
in one place.

File: docs/operator/auth-threat-model.md (MODIFIED, +485 LOC)

Conventions held
================

* The Bundle 1 sections ("Threat actors", "Defenses Bundle 1
  ships", "Threats Bundle 1 does NOT close", "Compliance mapping",
  "Operator-facing checks", "Cross-references") stay structurally
  intact. Bundle 2 EXTENDS them; nothing is rewritten in place.
* `Last reviewed:` header bumped 2026-05-09 → 2026-05-10.
* Per the prompt's explicit instruction: "do NOT create a separate
  auth-threat-model-bundle-2.md companion." This commit is a
  single-file extension.

Changes
=======

Intro paragraph rewritten:
* From "Bundle 1 lands... Bundle 2 will be updated" to "Bundle 1
  AND Bundle 2 land." Sets the reader's expectation that this is
  the post-Bundle-2 doc.

Threat actors section (4 new actors appended):
* OIDC-federated end user (token-forgery / session-hijacking /
  group-claim-manipulation surface).
* Stolen session cookie holder (XSS / network MITM / pasted-token).
* Compromised IdP (rogue token issuance; mitigations bounded to
  audit trail + group-mapping configuration).
* Break-glass-password holder (Phase 7.5 path bypasses OIDC + group
  layer entirely; default-OFF is the load-bearing mitigation).

NEW: Defenses Bundle 2 ships (5 sub-sections):
* OIDC token validation (Phase 3) — alg allow-list, IdP-downgrade
  defense, exact iss match, aud + azp checks, at_hash
  REQUIRED-when-access_token-present (Phase 3 tightening of OIDC
  core's MAY → MUST), single-use state + nonce, PKCE-S256 mandatory,
  iat window, JWKS rotation handling, JWKS-fetch-fail closed,
  encrypted client_secret at rest.
* Session minting + cookies (Phases 4 + 6) — length-prefixed HMAC
  defeating concatenation collision, HttpOnly + Secure + SameSite
  cookie hardening, idle + absolute timeouts, CSRF defense via
  double-submit-cookie + hashed-token-on-row, optional IP/UA bind,
  signing-key rotation primitive with retention window, fail-fatal
  EnsureInitialSigningKey at boot, pre-login vs post-login cookie
  discrimination.
* Back-channel logout (Phase 5) — OpenID Connect Back-Channel
  Logout 1.0 (NOT RFC 8414), required-claim pinning, jti-based
  replay defense, alg allow-list applies, Cache-Control: no-store.
* OIDC first-admin bootstrap (Phase 7) — coexists with Bundle 1's
  env-var-token bootstrap, group-scoped, one-shot per tenant via
  admin-existence probe, explicit OIDC provider gate, audit row on
  every grant.
* Break-glass admin (Phase 7.5) — default-OFF, surface-invisibility
  via 404-not-403, Argon2id with OWASP 2024 params, lockout state
  machine, constant-time across all failure paths via verifyDummy,
  WARN log at boot when ENABLED=true, 5/min rate limit on the
  public login endpoint.

NEW: Bundle 2 threat catalogue (8 sub-sections, one per
prompt-enumerated threat axis):

1. OIDC token forgery vectors and mitigations (9-row table covering
   alg confusion, audience injection, issuer mismatch, nonce replay,
   state replay, at_hash substitution, iat window manipulation,
   JWKS rotation mid-login, JWKS-fetch failure during a key
   rotation).
2. Session hijacking vectors and mitigations (7-row table covering
   XSS cookie theft, network MITM, CSRF, concatenation-collision
   forgery, stolen-cookie replay, cross-tab interference, sign-out
   race).
3. IdP compromise scenarios (operator monitors IdP audit logs,
   operator can rotate group-role mappings without redeploying,
   audit trail records source provider, provider-delete returns
   409 with active sessions).
4. Back-channel logout failure modes (6-row table covering IdP
   unreachable, invalid signature, replay via jti, alg confusion,
   missing events claim, present-nonce-claim).
5. Group-claim manipulation (4-row table covering operator
   misconfigured mapping, misconfigured groups_claim_path, IdP
   renames a group, IdP user maintainer adds user to unintended
   group).
6. Bootstrap phase risks post-Bundle-2 (4-row table covering
   CERTCTL_BOOTSTRAP_TOKEN leak, CERTCTL_BOOTSTRAP_ADMIN_GROUPS
   misconfigured to a wide group, both bootstrap strategies
   simultaneously, multi-IdP without explicit provider gate).
7. Break-glass risks (7-row table covering phished password,
   online brute-force, offline brute-force on DB compromise,
   operator forgets to disable, side-channel timing on
   wrong-vs-no-credential-vs-locked, surface fingerprinting,
   reserved-actor mutation).
8. Token-leak hygiene (the explicit grep policy with three
   per-package logging_test.go pointers + the audit_redact.go
   defense-in-depth note).

Threats Bundle 1 does NOT close section relabeled:
* Section header now reads "Threats Bundle 1 does NOT close
  (Bundle 2 closure status)" with each item carrying  / ⚠️ /
  "still deferred" markers.
* Items 1, 2, 3, 8 marked  closed by Bundle 2.
* Items 4, 5, 7, 9 marked still-deferred with v3 / follow-on
  pointers.
* Item 6 (rate limiting on bootstrap) marked acceptable; Bundle 2
  adds the same rate-limit primitive to /auth/breakglass/login.

NEW: Threats Bundle 2 does NOT close section listing the 8 v3 /
future-work items:
* WebAuthn / FIDO2 second factor (Decision 12).
* Time-bound role grants / JIT elevation.
* SAML federation (operators broker through Keycloak).
* Multi-tenant data isolation activation (gated to managed-service
  hosting work).
* HSM / FIPS-validated signing key for sessions.
* OIDC RP-initiated logout (Bundle 2 implements only back-channel).
* GUI E2E via Playwright.
* Per-IdP runbook external-tester sign-off (encouraged, NOT a merge
  gate post-2026-05-10 policy change).

Operator-facing checks section extended:
* 6 new SQL-shaped checks for Bundle 2 (provider count drift,
  per-actor session count, unmapped-groups audit-row spike,
  break-glass usage outside incidents, OIDC first-admin one-row-per-
  tenant invariant, retired-signing-key GC liveness).

Cross-references section split into Bundle 1 anchors + Bundle 2
anchors:
* Bundle 2 anchors enumerate every load-bearing file: 6
  internal/auth/ packages, 5 migrations, 3 ci-guards.

Compliance mapping section UNCHANGED:
* Phase 15 (standards-and-RFC-implementation table) is the proper
  home for the RFC + CWE evidence the Bundle 2 surface adds.
  Re-introducing framework-mapping prose at the threat-model layer
  would regress the operator's 2026-05-05 retired-compliance-docs
  decision, which is explicitly forbidden by the Phase 15 prompt.

Verification
============

* `> Last reviewed: 2026-05-10` — confirmed via head -3.
* All 8 prompt-mandated Bundle 2 threat sub-sections present —
  confirmed via grep `^### ` count (19 ### headers total: 6 Bundle
  1 + 5 Bundle 2 defenses + 8 Bundle 2 threats).
* All 39 prompt-listed threat-vector keywords present — confirmed
  via single-line grep counting 39 hits across the prompt's
  vocabulary.
* Internal markdown links resolve cleanly — confirmed via shell
  loop iterating each `]( ...)` reference and checking `[ -e "$path" ]`.
* No backend / Go-test impact — pure docs commit.
* `make verify` gate unchanged.
2026-05-10 16:11:08 +00:00
..
2026-05-05 18:18:29 +00:00
2026-05-05 18:18:29 +00:00
2026-05-05 18:18:29 +00:00