Finish KEY-WP-0008: registration handoff and client MFA isolation
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 34s

Add signed registration/enrollment handoffs, per-request assurance
policy with login-session isolation, and /logout. coulomb-social
stays AAL1 unless acr_values or another client raises the bar.
This commit is contained in:
tegwick 2026-08-16 01:05:27 +02:00
parent fff9e39478
commit b6af6c5268
22 changed files with 1636 additions and 42 deletions

View file

@ -4,11 +4,11 @@ type: workplan
title: "Registration handoff and client-aware MFA policy"
domain: infotech
repo: key-cape
status: active
owner: codex
status: finished
owner: grok
topic_slug: netkingdom
created: "2026-08-09"
updated: "2026-08-09"
updated: "2026-08-16"
depends_on:
- NK-WP-0025
state_hub_workstream_id: "70b78f21-be6d-4d6c-a537-037c38b2884a"
@ -36,11 +36,17 @@ normal authorization flow and must not mint a token directly.
Done when unknown users can choose signup from an eligible authorization flow
without open redirect, client substitution, or state replay.
Implemented `prompt=create` and `/authorize/register` against the client's
static `registrationUrl`, plus HMAC-signed `kc_handoff` envelopes consumed
once at `/authorize/return`. Return restarts `/authorize` and never mints a
code. Ineligible clients get no signup link. Live registration entry remains
user-engine-owned per NK-WP-0025; KeyCape only issues the return envelope.
## T02 - Replace global MFA with client-aware minimum assurance
```task
id: KEY-WP-0008-T02
status: progress
status: done
priority: high
state_hub_task_id: "c2b56182-e717-4ca3-84e3-0963b69ce32f"
```
@ -58,6 +64,13 @@ Implemented with nullable per-client `mfaRequired`: an explicit client value
overrides the provider default only for that client. Absent values preserve
the existing provider-driven policy.
2026-08-16: `DecideAssurance` now combines client minimum, requested ACR,
provider default, `max_age`, `prompt=login`, and current KeyCape login-session
level. An AAL1 session cannot satisfy an AAL2 client or `acr_values=aal2`.
`coulomb-social` in `config/dev-config.yaml` is `mfaRequired: false`; other
clients keep the provider default. Users without an enrolled factor are sent
to the client's `enrollmentUrl` instead of completing authorization.
## T03 - Support explicit step-up and fresh authentication
```task
@ -83,7 +96,7 @@ and `mfa: true` only after successful verification.
```task
id: KEY-WP-0008-T04
status: todo
status: done
priority: high
state_hub_task_id: "d4208f77-f4a6-4f2e-a436-de4f779cfaca"
```
@ -95,3 +108,11 @@ Keep static client registration and exact redirect rules unchanged.
Done when existing high-assurance clients pass unchanged and the new
coulomb-social journey passes live.
2026-08-16: isolation tests cover known/unknown users, registration
eligibility, state expiry/replay, password-only coulomb-social, ACR step-up,
no-factor enrollment handoff, OpenBao mandatory MFA, cross-client AAL1
session reuse, logout, and exact redirect enforcement. Full Go suite passes.
Live coulomb-social AAL1/AAL2 isolation was already proven on railiance01
under NK-WP-0025-T05 (2026-08-14); this closeout adds the KeyCape-side
regression suite and `/logout`.