- playbook-capability-contract_v0.2.md (proposed): adds the execution-attribution receipt field list (NK-WP-0040-T01). - iam-profile_v0.4.md (proposed): adds the workload-requested step-up contract (acr_values, no-factor refusal, assurance.level to flex-auth) (NK-WP-0042-T01). - Route the remaining externally-owned decisions (NK-WP-0040-T02 to audit-core/Railiance, NK-WP-0042-T02 to user-engine, NK-WP-0039-T04 to flex-auth/tenant-engine) and mark those workplans blocked. Assistant: claude-code Assistant-Model: sonnet Assistant-Process: 321494@bnt-lap001 Assistant-Session: 2c8a5cd1-573e-4bae-ab2b-29bc6c8ed4e9
99 lines
4.4 KiB
Markdown
99 lines
4.4 KiB
Markdown
---
|
|
id: netkingdom-iam-profile-v0.4
|
|
type: standard
|
|
title: "NetKingdom IAM Profile v0.4"
|
|
domain: netkingdom
|
|
status: proposed
|
|
owner: net-kingdom
|
|
created: "2026-09-27"
|
|
updated: "2026-09-27"
|
|
scope: core-platform
|
|
supersedes:
|
|
- canon/standards/iam-profile_v0.3.md
|
|
adr:
|
|
- docs/adr/ADR-0011-iam-profile-ownership-and-version-governance.md
|
|
- docs/adr/ADR-0016-mfa-user-preference-and-workload-step-up.md
|
|
related:
|
|
- NK-WP-0042
|
|
---
|
|
|
|
# NetKingdom IAM Profile v0.4
|
|
|
|
Everything in v0.3 stands unchanged except where this document says
|
|
otherwise. v0.3 remains `accepted` and normative; this document adds the
|
|
workload-requested step-up contract as a proposed amendment
|
|
(`NK-WP-0042-T01`). It does not require any workload to request MFA;
|
|
ADR-0016's default — MFA is a user preference — is unchanged, and the
|
|
enrollment/recovery usability gate in ADR-0016 §4 still applies before any
|
|
workload turns a requirement on.
|
|
|
|
## Workload-Requested Step-Up (proposed)
|
|
|
|
ADR-0016 lets a workload require AAL2 for all or part of its features
|
|
instead of leaving MFA to user preference. This section defines the
|
|
OIDC-level request and the no-factor refusal contract so every issuer
|
|
implements the same interface. **key-cape owns the implementation**; this
|
|
profile owns the interface, per NK-WP-0042-T01.
|
|
|
|
### Requesting step-up
|
|
|
|
- **Whole-client requirement.** A workload that requires AAL2 for all of
|
|
its sign-ins registers this at the client, unchanged from the existing
|
|
lightweight-mode client configuration (`mfaRequired` / P06 semantics).
|
|
This subsection does not change that path.
|
|
- **Per-request step-up.** A workload that requires AAL2 only for a
|
|
protected feature sends `acr_values` on the authorization request,
|
|
containing one of the `assurance.level` values this profile already
|
|
defines: `aal2` or `aal3`. The issuer MUST treat a recognized
|
|
`assurance.level` value in `acr_values` as a request for that floor.
|
|
- `max_age` MAY be combined with `acr_values` to also force a fresh
|
|
interactive login. `max_age` MUST NOT be used alone to request
|
|
strength: it bounds session age, not factor count. A request carrying
|
|
only `max_age` gets a fresh login at whatever assurance the user
|
|
already holds, not an implied AAL2.
|
|
- A request MUST NOT use a provider-native `acr` value as a substitute for
|
|
the profile's `assurance.level` vocabulary. Provider-native `acr`/`amr`
|
|
claims remain informational (Assurance Evidence, v0.3).
|
|
|
|
### No-factor refusal
|
|
|
|
If the requested floor is `aal2` or higher and privacyIDEA (or the
|
|
issuer's equivalent authoritative factor source) reports no active
|
|
factor for the user, the issuer MUST NOT silently issue a token at a
|
|
lower `assurance.level`. It MUST do one of:
|
|
|
|
- **Inline enrollment detour:** present the enrollment flow itself and,
|
|
on completion, resume and complete the original authorization request;
|
|
or
|
|
- **Explicit refusal:** fail the authorization request with an
|
|
OAuth-shaped error distinct from a generic `access_denied` (e.g.
|
|
`error=mfa_required`), so the requesting client can route the user to
|
|
enrollment itself.
|
|
|
|
Silent issuance of `assurance.level: aal1` (or omission of `assurance`)
|
|
in response to an `acr_values` request for `aal2`/`aal3` is nonconforming.
|
|
This governs the machine contract only; which of the two options a given
|
|
workload presents, and the exact enrollment/recovery UX, is
|
|
`NK-WP-0042-T02`'s open agreement with user-engine (U06) and a pilot
|
|
workload — this profile does not decide it.
|
|
|
|
### Reaching flex-auth
|
|
|
|
No new claim is introduced. The outcome is carried by the existing
|
|
`assurance.level` claim on the issued token (Assurance Evidence, v0.3):
|
|
a workload's per-request requirement is satisfied, refused, or detoured
|
|
before a token is issued, and flex-auth continues to read the issued
|
|
`assurance.level` exactly as the Identity To Authorization Contract table
|
|
already specifies. flex-auth MUST NOT infer a "requested vs. granted"
|
|
distinction from any other claim; there is only the token that was
|
|
issued.
|
|
|
|
### Non-goals
|
|
|
|
- This does not lower the IAM Profile v0.3 floor: privileged, destructive,
|
|
platform-root, secret, credential-vending, and emergency flows still
|
|
require `aal2` or stronger regardless of workload opt-in (ADR-0016 §3).
|
|
- This does not specify the enrollment/recovery user experience
|
|
(NK-WP-0042-T02) or which workloads turn step-up on (ADR-0016 §4).
|
|
- This does not add a Keycloak-specific or privacyIDEA-specific
|
|
mechanism; `acr_values` is the profile-level, provider-neutral request.
|