Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a092fe-13b1-7f12-ac74-7d258af4d79c
69 lines
4.7 KiB
Markdown
69 lines
4.7 KiB
Markdown
# 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 (including 11dfaf5 and 58e07dd).
|
|
- 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.
|