Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
4.7 KiB
P04 administrator recovery release — 2026-09-13
P04 is implemented and deployed. Entry: https://users.coulomb.social/platform/factor-recovery. A platform operator signs in with MFA within five minutes, enters the exact directory login and support reference, reviews one factor and shared-identity scope, and attests that the person's ownership was verified through the support process. A missing attestation denies the operation; the software does not pretend a checkbox independently proves ownership.
Recovery disables one selected factor and preserves password, directory identity, tenant access and other factors. Provider audit persists before mutation; stale state, changed ownership and conflicting references are rejected. PostgreSQL advisory locking serializes recovery requests; row locking protects the selected factor and its ownership records and a final fingerprint protects readback. Retries reconcile completion. Check recovery result by support reference if the page or response was lost; the original administrator can obtain a fresh confirmation for an interrupted operation. A completed receipt is rechecked against current provider state.
The private provider-side service independently verifies RS256 signature, exact KeyCape issuer and portal audience, human platform-operator role and fresh AAL2 assurance. Actor comes from the signed subject. Confirmation tickets bind actor, target, version, realm, support reference and expiry. Portal sessions retain the signed ID token server-side; it is never rendered into HTML or receipts. The portal receives no provider credentials or Kubernetes permissions. Network policy permits the recovery endpoint only from portal pods. Public signing-key access is separately scoped. No OpenBao owner handoff is needed for routine recovery.
The user then signs in to https://pink-account.coulomb.social with their own
password, enrolls a replacement TOTP, proves possession and tests a fresh
application login. The live keycape-confirm-totp-enrollment policy requires
possession confirmation for new TOTP enrollments in coulomb. Existing factors
were not changed. KeyCape already requires confirmed enrollment and OTP evidence
before AAL2. Recovery does not automatically relax application MFA policy.
Release and verification
- Portal source:
c298cd9(including11dfaf5and58e07dd). - Portal image: forgejo.coulomb.social/coulomb/user-engine@sha256:c71c6653132611de0c5f1209ca641ecefcde0df49a824930c6365a9fdecd3235.
- Provider service source: key-cape 63b3070 (including d15f4dd and cb51584).
- Immutable service code: mfa/factor-recovery-79e2964c112f3688.
- Provider image: ghcr.io/gpappsoft/privacyidea-docker@sha256:af7841adad262f129e0c1d4f553af13f21cb2f4dc713533f316cfe43ed0b4473.
- net-kingdom deployment procedure: sso-mfa/k8s/privacyidea/deploy-factor-recovery.py; possession policy: enable-factor-confirmation.py. Cluster and deployment UID checks plus resource-version preconditions protect rollout targets.
- 219 portal regression tests passed with disposable PostgreSQL, no skips.
- 15 recovery core/service tests passed, including lost-confirmation reconciliation.
- 19 isolated Chromium checks passed, including P04 role denial, scope/proof confirmation, completion receipt and replacement instructions.
- Installed-provider Job provider-p04-contract-03 passed signed administrator recovery, wrong role/audience, stale MFA, unsigned requests, unknown-user isolation, multi-owner factor refusal, tampered confirmation, durable audit, retry, reference readback, replacement possession and authentication. Its databases, identities, JWT signing key and OTP seeds were disposable fixtures, not production accounts.
- Exact source CI passed: KeyCape run61; portal runs166/167/168.
- Native PostgreSQL advisory and token/ownership locking queries passed against a nonexistent token ID and were rolled back; no factor rows were changed.
- Both deployments completed rollout. Live portal health/readiness returned 200; anonymous recovery page returned 403 with sign-in recovery navigation. Native portal-to-provider health returned 200; missing/invalid authentication returned 403. Provider signing-key access and policy readback passed.
No real user's authenticator was disabled for testing. Production authenticated recovery was not exercised against a real account; positive mutation and browser acceptance used disposable fixtures. P05 service operations and P06 broader policy/self-service work remain USER-WP-0030-T03; P04 is removed from that gap.
Shared factors (one serial assigned to multiple identities) are explicitly refused before mutation, with a clear ownership-resolution message. This preserves the bounded single-identity recovery contract.