--- id: NK-WP-0012 type: workplan title: "NetKingdom IAM Profile Specification" domain: netkingdom repo: net-kingdom status: finished owner: worsch topic_slug: netkingdom planning_priority: high planning_order: 12 created: "2026-05-21" updated: "2026-05-22" depends_on: - NK-WP-0006 state_hub_workstream_id: 9b8e4afc-eb71-47d9-8750-799a082b320a enables: - NK-WP-0011 --- # NK-WP-0012 — NetKingdom IAM Profile Specification > The IAM Profile is referenced everywhere as "the contract all applications > target," but it does not exist as a net-kingdom artifact. A draft **v0.1 > exists in the-custodian canon** (`canon/standards/iam-profile_v0.1.md`), > scoped "all-hubs" and Custodian-flavored. SCOPE.md says net-kingdom owns > the IAM Profile. This workplan resolves that: net-kingdom becomes the > canonical owner, and the profile is made provider-neutral, tenant- and > agent-aware, and conformance-testable. ## Goal Produce the **canonical, versioned NetKingdom IAM Profile** in net-kingdom canon — the OIDC/PKCE contract every implementation issues and every application and the authorization layer consume — together with an **executable conformance check**. The profile is the contract that makes the rest of the architecture coherent: - it is what `key-cape` (lightweight) and Keycloak (expanded) each implement, interchangeably (capability ladder C1/C5); - it is the identity input `flex-auth` consumes for authorization decisions (responsibility map: the identity layer owns the claim contract — that contract is this profile); - it is the thing **NK-WP-0011-T6** runs conformance checks against, so this workplan **enables** NK-WP-0011. ## Why now / what exists The v0.1 draft is a strong base — discovery contract, Authorization Code + PKCE human flow, service-account flow, required claims, token lifecycle, emergency/break-glass, and a local-development profile. But it has gaps for the current architecture: | Gap in v0.1 | Needed because | |---|---| | Lives in the-custodian, scoped "all-hubs" | net-kingdom owns the profile (SCOPE.md, responsibility map) | | Keycloak named as *the* reference provider | provider-neutral now: key-cape lightweight / Keycloak expanded are interchangeable implementations | | Scope/role vocabulary is hub-specific (`hub:*`, `ops:*`, `fin:*`) | the core profile must be platform-neutral; hub/app scopes are downstream extensions | | No tenant claim | recursive `tenant:platform` vs tenant model (NK-WP-0006) needs tenant in the token | | Only human/service identities | architecture distinguishes human / service / **agent** principals | | Assurance is implicit | flex-auth decision envelopes require explicit assurance evidence | | No executable conformance check | NK-WP-0011-T6 and every implementation need a runnable contract test | ## Scope In scope: - ownership and reconciliation decision (ADR) with the-custodian v0.1 - a provider-neutral, platform-neutral **v0.2** profile in net-kingdom canon - tenant- and agent-aware claims, and explicit assurance evidence - the identity→authorization claim contract consumed by flex-auth - an executable conformance check - versioning and breaking-change governance for the profile - migration of downstream references to the canonical net-kingdom spec Out of scope: - implementing the profile in key-cape or Keycloak (their repos own that) - defining tenant- or application-specific scope vocabularies - deploying any identity provider ## Tasks ```task id: NK-WP-0012-T1 state_hub_task_id: 284dda38-b778-445a-a7dc-9b5a12fa380f status: done priority: high ``` **Ownership & reconciliation decision (ADR-0011).** Record that net-kingdom is the canonical owner of the IAM Profile. Decide how the-custodian's all-hubs v0.1 reconciles: net-kingdom owns the **core/platform profile**; hub- and app-specific scope vocabularies (`hub:*`, `ops:*`, `fin:*`) become **downstream extensions** that map back to the core, not part of it. Define the profile's **versioning and breaking-change governance** (what a breaking change is, how downstream is notified, how versions coexist). ```task id: NK-WP-0012-T2 state_hub_task_id: 0070398d-b0a4-4c11-a6fa-000166e1108f status: done priority: high ``` **Author IAM Profile v0.2 (provider-neutral core).** Create `canon/standards/iam-profile_v0.2.md` in net-kingdom. Carry forward the solid v0.1 material — discovery contract, Authorization Code + PKCE human flow, service-account flow, required/recommended claims, token lifecycle, emergency/break-glass, local-development profile — and make it **provider-neutral**: key-cape (lightweight) and Keycloak (expanded) are named as interchangeable implementations, neither as "the" reference. Remove hub-specific vocabulary from the core. ```task id: NK-WP-0012-T3 state_hub_task_id: 6fc2a5e1-1480-42f1-86a2-3e714359e1ba status: done priority: high ``` **Extend for the recursive and agent model.** Add a **tenant** claim (`tenant:platform` vs tenant id), formalize the **human / service / agent** principal types and how each is represented, and define an explicit **assurance evidence** claim (how authentication strength / MFA is conveyed in the token). Align with NK-WP-0006 and the responsibility map. ```task id: NK-WP-0012-T4 state_hub_task_id: 0e52ed45-afa7-4832-9d6a-1ebbbab43872 status: done priority: high ``` **Define the identity→authorization claim contract.** Specify exactly which claims the profile guarantees as inputs to flex-auth decision envelopes — subject, issuer, audience, tenant, groups, roles, scopes, assurance — so flex-auth treats the profile as normative input and never re-derives identity. This is the contract named in the responsibility map. ```task id: NK-WP-0012-T5 state_hub_task_id: f0a62e77-b781-4625-b8bd-d191b48af58e status: done priority: high ``` **Executable conformance check.** Build a runnable suite that validates an issuer/implementation against the profile: discovery document completeness, PKCE enforcement, claim shape, JWKS and key-rotation tolerance, token validation (issuer/audience/expiry/signature), and rejection of local-development issuers in production. This is the artifact NK-WP-0011-T6 consumes; it must run against both a key-cape and a Keycloak issuer. ```task id: NK-WP-0012-T6 state_hub_task_id: a1fd53a9-526f-4d87-89db-6073710c885d status: done priority: medium ``` **Migration & cross-references.** Supersede or relink the-custodian v0.1 (deprecation note pointing at the net-kingdom canonical spec), and update downstream references — `key-cape` and `flex-auth` interface docs, NK-WP-0011, and any architecture docs — to cite the canonical net-kingdom profile. Per ADR-0010, downstream **intents** are not touched; only interface/reference docs. ## Acceptance Criteria - The canonical IAM Profile lives in net-kingdom canon, versioned, and an ADR records ownership and the reconciliation with the-custodian v0.1. - The core profile is provider-neutral and platform-neutral (no hub-specific scopes in the core; no single "reference provider"). - The profile carries tenant, principal-type (human/service/agent), and assurance claims, aligned with the recursive model. - The claims flex-auth consumes are specified as a normative contract. - An executable conformance check exists and passes against both a key-cape and a Keycloak issuer. - Versioning and breaking-change governance is documented. - Downstream reference docs point at the canonical spec; the custodian v0.1 carries a deprecation/relocation note. ## Completion Notes - ADR: `docs/adr/ADR-0011-iam-profile-ownership-and-version-governance.md` - Canonical profile: `canon/standards/iam-profile_v0.2.md` - Executable conformance suite: `tools/iam-profile-conformance/iam_profile_conformance.py` - Fixture tests cover key-cape-like and Keycloak-like issuers, local-dev rejection in production mode, tenant claim enforcement, provider-native role normalization warnings, and delegated-agent claim shape. - Cross-repo reference docs updated without touching downstream `INTENT.md`: key-cape README/spec references now point at v0.2, and flex-auth consumption docs plus claim fixtures now include v0.2 tenant, principal, and assurance inputs. ## Dependencies & Sequencing - **Depends on NK-WP-0006** for the recursive tenant model the claims encode. - **Enables NK-WP-0011** — T6 (IAM Profile conformance) cannot pass without the spec and the conformance check from this workplan. NK-WP-0012 should land before NK-WP-0011-T6. - Coordinates with **flex-auth** (the consumed claim contract, T4) and with **key-cape**/**Keycloak** as the implementations the conformance check runs against — those repos implement, this workplan specifies and tests. ## Resolved Questions - Canonical role claim: `roles` is canonical. `realm_access.roles` is a transitional/provider-native source that must be mapped before production consumption. - Audience granularity: the core profile requires the receiving service in `aud`; endpoint/resource granularity belongs to flex-auth resource/action policy. - Agent principals differ from service accounts through `principal_type: agent`, an `agent` object, and delegated actor context (`actor_sub` or `act.sub`) when applicable. - The conformance check is a standalone tool in net-kingdom for v0.2. Other repos consume it as an executable contract rather than importing a shared library for now.