net-kingdom/canon/standards/iam-profile_v0.4.md
tegwick b808da601d
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Draft execution-attribution and workload-step-up amendments; route remaining tasks
- 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
2026-09-27 23:59:51 +02:00

4.4 KiB

id type title domain status owner created updated scope supersedes adr related
netkingdom-iam-profile-v0.4 standard NetKingdom IAM Profile v0.4 netkingdom proposed net-kingdom 2026-09-27 2026-09-27 core-platform
canon/standards/iam-profile_v0.3.md
docs/adr/ADR-0011-iam-profile-ownership-and-version-governance.md
docs/adr/ADR-0016-mfa-user-preference-and-workload-step-up.md
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.