Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
193 lines
10 KiB
Markdown
193 lines
10 KiB
Markdown
---
|
|
id: NK-WP-0042
|
|
type: workplan
|
|
title: "Let workloads require MFA for all or part of their features"
|
|
domain: infotech
|
|
repo: net-kingdom
|
|
status: finished
|
|
flavor: planning
|
|
owner: claude-code
|
|
topic_slug: netkingdom
|
|
created: "2026-09-23"
|
|
updated: "2026-10-10"
|
|
related: [NK-ADR-0016, NK-WP-0037]
|
|
state_hub_workstream_id: "3f702215-704b-5788-8ca0-b8b9ba2dd3f8"
|
|
---
|
|
|
|
ADR-0016 makes MFA a user preference by default and lets a workload require
|
|
it for all or some of its features. This workplan defines how a workload
|
|
states that requirement and how the flow enforces it. It does not require MFA
|
|
anywhere; the enrollment and recovery usability gate in ADR-0016 still
|
|
applies first.
|
|
|
|
## Specify the workload-requested step-up contract
|
|
|
|
```task
|
|
id: NK-WP-0042-T01
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "d66a6347-b714-5cca-aeb5-7121328f4dec"
|
|
```
|
|
|
|
Define how a workload requests AAL2: per client registration for the whole
|
|
feature set, or per request as a step-up when a protected feature is used.
|
|
Specify:
|
|
|
|
- which OIDC parameter the request uses (`acr_values`, `max_age`, or both);
|
|
- what KeyCape must return when a user has no factor (a clean refusal and an
|
|
enrollment route, never silent AAL1);
|
|
- how the resulting `assurance.level` reaches flex-auth.
|
|
|
|
Record it as an IAM Profile amendment. key-cape owns the implementation.
|
|
|
|
**Done 2026-09-27.** Drafted as `canon/standards/iam-profile_v0.4.md`
|
|
(status `proposed`, supersedes v0.3, which stays `accepted` and normative
|
|
until this is accepted). The new "Workload-Requested Step-Up (proposed)"
|
|
section specifies `acr_values` carrying an `assurance.level` value
|
|
(`aal2`/`aal3`) as the step-up request, `max_age` as an optional additive
|
|
freshness request that must never stand in for strength alone, the two
|
|
conforming no-factor refusal shapes (inline enrollment detour or an
|
|
explicit `error=mfa_required`-class refusal, never silent AAL1), and that
|
|
flex-auth keeps reading the issued `assurance.level` with no new claim.
|
|
The exact enrollment/recovery UX is left to T02, which this section names
|
|
explicitly.
|
|
|
|
## Agree the user-facing step-up and enrollment journey
|
|
|
|
```task
|
|
id: NK-WP-0042-T02
|
|
status: cancel
|
|
needs_human: false
|
|
closure_reason: "Duplicate attended acceptance consolidated into existing USER-WP-0027-T04 and USER-WP-0028-T03; decision cef97ccd remains open there. Demand-deferred workload-requested interoperability retained in residual NET-IN-0003."
|
|
priority: medium
|
|
state_hub_task_id: "4e51585d-2b57-56d4-84c1-314041d26bcf"
|
|
```
|
|
|
|
With user-engine (U06, factor recovery) and one pilot workload, agree what a
|
|
user sees when a feature needs MFA and they have none. That includes the
|
|
enrollment detour, the return to the feature, and recovery. It must be
|
|
accepted from a user's perspective before any workload turns the requirement
|
|
on.
|
|
|
|
**Waiting 2026-09-27.** Routed to user-engine via State Hub message
|
|
`892fd489-113d-4108-8048-727f4b0ed048`, referencing the T01 contract and
|
|
asking for a proposed pilot workload and U06 touchpoints. This is a
|
|
UX/product agreement across two repos and a pilot workload owner; NetKingdom
|
|
cannot decide it unilaterally.
|
|
|
|
2026-10-03: human gate routed to hub decision cef97ccd-4ee7-40fe-859e-1df9c9360ecb (D10: Identity record and MFA: accept NK-ADR-0017, choose the record read surface, agree the MFA user experience) by CUST-WP-0075; resolving that decision raises C-40 here.
|
|
|
|
2026-10-03 (CUST-WP-0075 inbox sweep): gate re-checked, unchanged. The unread
|
|
user-engine message of 2026-10-03 (`db1b7d6e`, USER-WP-0026-T03) was about the
|
|
workload catalogue/admission and access-decision owner, not this journey; it
|
|
was answered (reply `19a0cbcd`: access-engine owns decisions, grants,
|
|
revocation and the protected-system registry; the catalogue is the onboarding
|
|
binding of access-engine protected system, key-cape OIDC client and user-engine
|
|
application record; NetKingdom only orchestrates). It does not settle T02. Our
|
|
2026-09-27 request `892fd489` (pilot workload, U06 touchpoints) is still unread
|
|
by user-engine, so `blocked_on: message-from:user-engine` stays real, and the
|
|
founder's acceptance under decision cef97ccd stays the human gate. The reply
|
|
reminds user-engine of `892fd489`.
|
|
|
|
2026-10-09: user-engine answered `892fd489` (message `a459e8a6`), as a proposal;
|
|
the pilot choice and the AAL2 switch-on stay founder decisions:
|
|
|
|
- Pilot workload: `coulomb-social` (the current registration/onboarding client,
|
|
owner of application action step-up). One non-privileged feature behind
|
|
`acr_values=aal2`. Precedent: the user-engine portal's administration step-up
|
|
("Verify with MFA" -> `/login?recovery=1&return_path=...`, P06 recent-MFA
|
|
guard, deployed).
|
|
- Refusal shape: inline enrollment detour at the issuer; factor screens stay on
|
|
the IdP and user-engine never collects an OTP or reads a seed. Fallback on an
|
|
`mfa_required`-class refusal: link to the public user-engine `/security`
|
|
page. Return means the workload re-requests with `acr_values`; a return URL is
|
|
never proof of enrollment.
|
|
- U06 touchpoints reused: `/security`; My account -> Sign-in security ->
|
|
provider management (`USER_ENGINE_MFA_MANAGEMENT_URL`, deliberately unset
|
|
until attended KEY-WP-0035 self-service checks pass); U07 lost device and U08
|
|
replace/remove (replacement verified before removal, no bypass link; P04
|
|
operator-assisted recovery); P06 policy preview/rollback so switching on does
|
|
not lock out unenrolled users.
|
|
- Constraint: user-engine's attended real-factor U05-U08 run
|
|
(USER-WP-0027-T03 / USER-WP-0028-T03) is pending, and route
|
|
`net-kingdom-privacyidea-admin-token` is still `resolvable: false`
|
|
(railiance-platform). user-engine proposes running the pilot's
|
|
user-perspective acceptance in that same attended session (enrollment detour
|
|
-> return -> lost-factor recovery, end to end once).
|
|
|
|
NetKingdom's reading: the proposal fits the T01 contract (issuer owns factor
|
|
screens, workload enforces issued assurance, return is not evidence). The
|
|
message dependency is cleared; T02 stays `wait` on the founder under decision
|
|
cef97ccd: choose the pilot, then accept the journey in the combined attended
|
|
session. Note that coulomb.social fits oidc-browser-relying-party 1.0 only partly
|
|
(NK-WP-0048 README fit table), so the pilot's KeyCape `acr_values` handling is
|
|
checked on its existing registration.
|
|
|
|
2026-10-09: founder decision, relayed by user-engine (message `60673e40`;
|
|
recorded in user-engine `docs/mfa-pilot-decision.md`):
|
|
|
|
1. Pilot workload: `coulomb-social`.
|
|
2. MFA stays in NetKingdom infrastructure: enrollment, verification,
|
|
replacement, recovery and MFA-required policy live with KeyCape/issuer plus
|
|
the provider factor and user-engine (`/security`, P04, P06). coulomb-social
|
|
stays a plain OIDC relying party with no factor, enrollment, recovery or MFA
|
|
policy code.
|
|
3. MFA is optional for coulomb-social users: password-only stays valid (U05),
|
|
enrollment is voluntary via U06, and the issuer enforces the factor once a
|
|
user has enrolled (U07). No `acr_values=aal2` switch-on now.
|
|
4. Admin-required MFA for coulomb-social users is deferred and not urgent; when
|
|
wanted, it is an issuer-side client policy applied through the NetKingdom
|
|
admin surface (P06 preview/apply/rollback), with a separate founder go.
|
|
|
|
Consequence for this plan: the pilot proves the optional-after-enrollment
|
|
journey, not workload-requested step-up. The T01 `acr_values` contract stays
|
|
valid but unexercised by this pilot. Not settled: decision `cef97ccd` stays
|
|
open for user-perspective acceptance, which runs in user-engine's attended
|
|
U05-U08 session (USER-WP-0027-T04 / USER-WP-0028-T03) with a coulomb-social
|
|
user. T02 stays `wait` on that session.
|
|
|
|
## Infrastructure review — 2026-09-28
|
|
|
|
Build T02 on the already completed USER-WP-0033 and KEY-WP-0035 P06 work.
|
|
Their September 14 release evidence records optional-after-enrollment policy
|
|
for `user-engine-portal` and `vergabe-demo-company`, privileged MFA guards,
|
|
confirmed enrollment/cancellation and old-session checks. Do not rebuild
|
|
those capabilities or interpret this plan as the first delivery of MFA policy.
|
|
|
|
The residual is workload-level interoperability and an accepted pilot journey:
|
|
agree the pilot owner, reuse U06 recovery, prove no-factor enrollment and
|
|
return to the protected action, and test stale AAL1, refusal and provider
|
|
unavailability. Existing scoped policy does not prove arbitrary-client
|
|
`acr_values` support or acceptance of IAM v0.4. KeyCape owns issuer enforcement;
|
|
user-engine owns the journey; the workload and flex-auth enforce the issued
|
|
assurance at the protected action. T02 remains `wait` for that agreement and
|
|
actual-user acceptance, coordinated with KEY-WP-0034 / USER-WP-0028 /
|
|
VERGABE-WP-0019, without reopening their completed provider work.
|
|
|
|
Evidence and cross-plan priorities: [estate review](../history/2026-09-28-open-workplan-infrastructure-review.md).
|
|
|
|
## 2026-10-10 — Consolidated planning closure
|
|
|
|
This planning workplan is finished for its delivered contract proposal and
|
|
policy/pilot agreement; it does not claim a working arbitrary-client step-up
|
|
capability or accepted real-user MFA journey. T01 produced proposed IAM v0.4
|
|
while v0.3 remains normative. The founder's October 9 decision explicitly
|
|
selected optional MFA on coulomb-social, issuer/provider-held MFA mechanics
|
|
and no current acr_values=aal2 switch-on (user-engine/docs/mfa-pilot-decision.md;
|
|
owner relay 60673e40).
|
|
|
|
T02's remaining attended acceptance was already owned by live
|
|
USER-WP-0027-T04 and USER-WP-0028-T03 with the same decision cef97ccd.
|
|
user-engine/docs/mfa-attended-run.md now specifies the actual U05-U08 run
|
|
with tegwick, the approved client, the already-live management handoff, the
|
|
verification and evidence rules. USER-WP-0028 records founder approval of
|
|
tegwick/coulomb-social and the live handoff reply 7ee2459e on October 10.
|
|
T02 is cancelled only as a duplicate local acceptance gate: those existing
|
|
owners and decision remain open until observed acceptance. No MFA or browser
|
|
check has been marked complete.
|
|
|
|
Future workload-requested step-up interoperability (no-factor refusal,
|
|
enrollment return, stale AAL1 and provider outage) remains demand-deferred
|
|
under NET-IN-0003, origin residual / origin_ref NK-WP-0042, rather than
|
|
disappearing into closure prose. Do not implement that residual without
|
|
promotion and a separately approved client policy/rollout.
|