key-cape/workplans/KEY-WP-0035-optional-mfa.md

113 lines
5.5 KiB
Markdown
Raw Normal View History

---
id: KEY-WP-0035
type: workplan
title: "Opt-in MFA for demo-company login"
domain: infotech
repo: key-cape
status: finished
owner: codex
topic_slug: infotech
created: "2026-09-13"
updated: "2026-09-14"
state_hub_workstream_id: "b27601d8-d0a5-5c79-a1ff-c2a4cedafa74"
---
Requested behavior: password-only login before OTP activation; require OTP after
activation. Do not lower assurance of unrelated applications.
## Implement enrollment-dependent browser policy
```task
id: KEY-WP-0035-T01
status: done
priority: high
state_hub_task_id: "c1ed06c2-c689-53d1-afc7-e10d79e9e94f"
```
Add mfaOptional, preserve explicit AAL2 and existing client policy, fail closed on
provider lookup errors and malformed/incomplete responses. Preserve the setting
in config/runtime/canonical model and flag manual migration requirements.
Validation: `go test ./...` and `git diff --check` passed on 2026-09-13. See docs/optional-mfa.md.
## Restore authoritative factor lookup and enable the reviewed client
```task
id: KEY-WP-0035-T02
status: done
priority: high
state_hub_task_id: "b066a273-f91c-50ee-b497-a39eace03b3a"
```
Factor lookup restored on 2026-09-13 through the new dedicated service lane
RPF-WP-0040 / CCR-2026-0023. Native ESO delivery, scoped provider user lookup,
renewal and mounted replacement passed. KeyCape now uses adminTokenFile; other
configuration and current MFA policy were preserved. Historical NK-WP-0033
resolver lanes remain separate. The remaining T02 work is the exact scoped
client migration and no-factor/enrolled/error/step-up acceptance before enabling
optional policy. See railiance-platform/docs/evidence/2026-09-13-keycape-factor-custody.md.
## Verify optional enrollment and account management access
```task
id: KEY-WP-0035-T03
status: done
priority: high
state_hub_task_id: "93ce2e97-6c5a-58a7-8f3c-1c4f0eb6f1b5"
```
Verify provider self-service login, possession-confirmed activation, cancellation
and removal/recovery. Resolve shared portal assurance scope before surfacing the
verified OTP setup link. Actual user login acceptance remains open under
KEY-WP-0034 and VERGABE-WP-0019; this work does not finish either workplan.
## Support bounded provider credential renewal without issuer restart
```task
id: KEY-WP-0035-T04
status: done
priority: high
state_hub_task_id: "494f554d-6542-5797-804f-6df4a05dcadb"
```
Supports platform journey P05 and USER-WP-0030-T03. Add an exclusive mounted adminTokenFile credential source, fresh reads for lookup and validation, no stale fallback, bounded input, sanitized failures and atomic replacement acceptance. Preserve inline configuration compatibility. Require provider success and true validation value before AAL2; bound default request time and reject credential-bearing redirects. Test renewal, rejection, recovery and policy regressions. This implements the consumer delivery contract; owner credential issuance/custody and live P04/P05/P06 acceptance remain T02/T03.
All Go regression/conformance suites pass, including five new renewal/validation tests with invalid-source subcases. Added exact-commit authentication acceptance CI. Provider-mounted credential delivery and effective optional policy remain gated separately.
Consumer source 632b1f1 deployed and Ready 1/1; CI, four provider HTTP checks and twelve live browser checks passed. See docs/credential-renewal-release-2026-09-13.md. T02/T03 retain actual credential delivery and live recovery/policy acceptance.
2026-09-13 custody activation supersedes the earlier owner-handoff gate: the new factor service is live and renewable. T02/T03 now track effective policy/onboarding acceptance, not missing credential ownership.
## Require confirmed enrollment and actual OTP evidence
```task
id: KEY-WP-0035-T05
status: done
priority: high
state_hub_task_id: "94f579d1-a7af-564c-ab0c-ae76fce343aa"
```
Live provider source inspection found active tokens can remain in verification
state; live policy inspection found password passthrough enabled for users without
factors. Distinguish pending enrollment from completed enrollment and require
TOTP/HOTP serial/type evidence before AAL2. Cover pending/confirmed/cancelled,
existing-factor plus pending enrollment, missing/unknown state, incomplete pages,
password passthrough and static-password token rejection. All Go suites pass
locally; source 113f3a6 was published, CI acceptance/build passed, and the guarded issuer replacement is live. See docs/enrollment-assurance-release-2026-09-13.md.
Provider recovery testing additionally proved that withdrawing reader policy
returns HTTP 200 with an empty list. Added and deployed a same-realm disabled,
unassigned visibility probe before no-factor decisions, with missing visibility
failing closed. Native scope proof passed. Isolated installed-provider tests
passed possession confirmation/cancellation, permission withdrawal/recovery and
provider-issued JWT expiry; these are now included in CI. T02/T03 remain the
actual optional-client and self-service browser activation gates.
2026-09-14: T02/T03 completed through USER-WP-0033 P06. Installed-provider
native and five browser checks passed, including confirmed activation,
cancellation, old-session MFA and denied active-factor replacement. Portal
guards, provider restrictions and both scoped optional-client policies are live;
PVC readback confirms effective state. Full release evidence and rollback:
`../user-engine/docs/evidence/2026-09-13-p06-authentication-policy.md`.
Residual actual-user and workload sign-in acceptance remains live under
KEY-WP-0034, USER-WP-0028 and VERGABE-WP-0019 before this closure.