generated from coulomb/repo-seed
Implement NK-WP-0012 IAM profile specification
This commit is contained in:
391
canon/standards/iam-profile_v0.2.md
Normal file
391
canon/standards/iam-profile_v0.2.md
Normal file
@@ -0,0 +1,391 @@
|
||||
---
|
||||
id: netkingdom-iam-profile
|
||||
type: standard
|
||||
title: "NetKingdom IAM Profile v0.2"
|
||||
domain: netkingdom
|
||||
status: accepted
|
||||
version: "0.2"
|
||||
created: "2026-05-22"
|
||||
updated: "2026-05-22"
|
||||
scope: core-platform
|
||||
supersedes:
|
||||
- the-custodian/canon/standards/iam-profile_v0.1.md
|
||||
adr:
|
||||
- docs/adr/ADR-0011-iam-profile-ownership-and-version-governance.md
|
||||
---
|
||||
|
||||
# NetKingdom IAM Profile v0.2
|
||||
|
||||
## Purpose
|
||||
|
||||
The NetKingdom IAM Profile is the provider-neutral OIDC contract that
|
||||
identity implementations issue and applications consume.
|
||||
|
||||
It defines:
|
||||
|
||||
- OIDC discovery and endpoint requirements;
|
||||
- Authorization Code + PKCE for human login;
|
||||
- service-account and workload identity token requirements;
|
||||
- human, service, and agent principal representation;
|
||||
- tenant and platform-boundary claims;
|
||||
- explicit assurance evidence;
|
||||
- the identity-to-authorization claim contract consumed by flex-auth;
|
||||
- local-development and emergency-access behavior;
|
||||
- executable conformance expectations.
|
||||
|
||||
Applications target this profile, not a concrete identity provider.
|
||||
key-cape is the lightweight implementation. Keycloak is the expanded-mode
|
||||
implementation. Both are interchangeable at the application and
|
||||
authorization boundary when they conform to this document.
|
||||
|
||||
## Ownership
|
||||
|
||||
NetKingdom owns the core/platform profile. See ADR-0011.
|
||||
|
||||
Downstream systems may define extension scopes, roles, resource names,
|
||||
and tenant policy vocabularies. Those extensions are not part of the core
|
||||
profile unless a future version explicitly adopts them. Extension
|
||||
vocabularies must map back to the core claims in this document before
|
||||
flex-auth or applications consume them.
|
||||
|
||||
## Design Principles
|
||||
|
||||
- Consumers trust signed OIDC tokens, not provider-specific sessions.
|
||||
- Identity providers assert identity and authentication evidence; they do
|
||||
not make final resource authorization decisions.
|
||||
- The same profile works in lightweight key-cape mode and expanded
|
||||
Keycloak mode.
|
||||
- Tenancy is explicit. `tenant:platform` is distinct from tenant planes
|
||||
such as `tenant:coulomb`.
|
||||
- Human, service, and agent principals are distinguishable.
|
||||
- Assurance evidence is explicit enough for flex-auth policy.
|
||||
- Local-development issuers are useful but never accepted by production.
|
||||
- Emergency access is auditable, time-bounded, and reviewable.
|
||||
|
||||
## Discovery Contract
|
||||
|
||||
Every IAM Profile implementation MUST expose OIDC discovery at:
|
||||
|
||||
```text
|
||||
GET <issuer>/.well-known/openid-configuration
|
||||
```
|
||||
|
||||
The discovery response MUST include:
|
||||
|
||||
| Field | Requirement |
|
||||
| --- | --- |
|
||||
| `issuer` | Exact issuer identifier used in tokens |
|
||||
| `authorization_endpoint` | Required for human Authorization Code + PKCE |
|
||||
| `token_endpoint` | Required for token exchange and service accounts |
|
||||
| `jwks_uri` | Required for signature validation |
|
||||
| `userinfo_endpoint` | Required when userinfo is supported by the flow |
|
||||
| `scopes_supported` | MUST include `openid`; SHOULD include `profile` and `email` |
|
||||
| `response_types_supported` | MUST include `code` |
|
||||
| `grant_types_supported` | MUST include `authorization_code`; MUST include `client_credentials` or a documented workload-token exchange for service identities |
|
||||
| `id_token_signing_alg_values_supported` | MUST include the implementation signing algorithm; RS256 is required for v0.2 conformance |
|
||||
| `code_challenge_methods_supported` | MUST include `S256` |
|
||||
|
||||
The response SHOULD include `end_session_endpoint` where logout is
|
||||
supported and `claims_supported` listing the core claims below.
|
||||
|
||||
Consumers MUST discover endpoints and key material from the issuer
|
||||
metadata instead of hardcoding provider-specific paths.
|
||||
|
||||
## Required Flows
|
||||
|
||||
### Human Interactive Flow
|
||||
|
||||
Human users authenticate with Authorization Code + PKCE.
|
||||
|
||||
Required properties:
|
||||
|
||||
- PKCE with `S256` is mandatory for browser and CLI clients.
|
||||
- Implicit flow is not part of the profile.
|
||||
- MFA or equivalent strong assurance is mandatory for privileged,
|
||||
destructive, platform-root, and emergency access in production.
|
||||
- Access tokens are short-lived.
|
||||
- Refresh tokens are allowed only for trusted clients with explicit
|
||||
rotation and revocation.
|
||||
|
||||
### Service Account Flow
|
||||
|
||||
Service-to-service traffic uses client credentials or a deployment's
|
||||
documented workload identity token-exchange equivalent.
|
||||
|
||||
Required properties:
|
||||
|
||||
- Service subjects are stable and named for service plus environment.
|
||||
- Secrets or workload credentials are delivered through the
|
||||
credential-management standard, not plaintext configuration.
|
||||
- Tokens include an audience that identifies the target service.
|
||||
- Tokens carry `principal_type: service`.
|
||||
- Service accounts receive only required scopes and roles.
|
||||
- Credentials are rotated and never shared between environments.
|
||||
|
||||
### Agent Principal Flow
|
||||
|
||||
Agents are automation principals that may act autonomously or under
|
||||
delegated authority.
|
||||
|
||||
Required properties:
|
||||
|
||||
- Tokens carry `principal_type: agent`.
|
||||
- Tokens include an `agent` object with `id` and `mode`.
|
||||
- `agent.mode` is `autonomous` or `delegated`.
|
||||
- Delegated agents MUST identify the delegating actor using `actor_sub`
|
||||
or an equivalent `act.sub` claim.
|
||||
- Agent tokens MUST carry the tenant they operate within.
|
||||
- Agent tokens MUST include assurance evidence for both the agent
|
||||
credential and any delegated human authority when policy needs it.
|
||||
|
||||
## Core Claims
|
||||
|
||||
Access tokens accepted by production consumers MUST provide the following
|
||||
claims after provider mapping or normalization:
|
||||
|
||||
| Claim | Type | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `iss` | string | OIDC issuer URL or issuer identifier |
|
||||
| `sub` | string | Stable subject identifier unique within `iss` |
|
||||
| `aud` | string or array | Intended audience; MUST include the receiving service |
|
||||
| `exp` | number | Expiry timestamp |
|
||||
| `iat` | number | Issued-at timestamp |
|
||||
| `nbf` | number | Not-before timestamp, recommended for production tokens |
|
||||
| `jti` | string | Token identifier, recommended for audit and replay controls |
|
||||
| `tenant` | string | Tenant identifier such as `tenant:platform` or `tenant:coulomb` |
|
||||
| `principal_type` | string | `human`, `service`, or `agent` |
|
||||
| `groups` | array | Group memberships, possibly empty |
|
||||
| `roles` | array | Coarse identity roles, possibly empty |
|
||||
| `scope` or `scp` | string or array | Granted OAuth scopes |
|
||||
| `assurance` | object | Authentication and credential assurance evidence |
|
||||
|
||||
Recommended human claims:
|
||||
|
||||
| Claim | Meaning |
|
||||
| --- | --- |
|
||||
| `preferred_username` | Human-readable username |
|
||||
| `email` | Contact identity |
|
||||
| `name` | Display name |
|
||||
|
||||
Recommended service claims:
|
||||
|
||||
| Claim | Meaning |
|
||||
| --- | --- |
|
||||
| `azp` or `client_id` | Authorized client/service identifier |
|
||||
| `service` | Object naming the service and environment |
|
||||
|
||||
Recommended agent claims:
|
||||
|
||||
| Claim | Meaning |
|
||||
| --- | --- |
|
||||
| `agent.id` | Stable agent identifier |
|
||||
| `agent.mode` | `autonomous` or `delegated` |
|
||||
| `actor_sub` or `act.sub` | Delegating subject for delegated agents |
|
||||
|
||||
### Role Claim
|
||||
|
||||
The canonical role claim is `roles`, an array of strings.
|
||||
|
||||
Expanded-mode Keycloak deployments may also expose provider-native roles
|
||||
such as `realm_access.roles`, but conforming tokens consumed by flex-auth
|
||||
or applications MUST either emit `roles` directly or pass through a
|
||||
normalizing adapter that produces `roles`.
|
||||
|
||||
### Scope Vocabulary
|
||||
|
||||
The core profile defines only OAuth/OIDC base scopes:
|
||||
|
||||
| Scope | Meaning |
|
||||
| --- | --- |
|
||||
| `openid` | Required for OIDC login |
|
||||
| `profile` | Basic profile claims |
|
||||
| `email` | Email claim where appropriate |
|
||||
| `offline_access` | Refresh-token capable access where explicitly allowed |
|
||||
|
||||
Hub-, application-, and resource-specific scopes such as `hub:*`,
|
||||
`ops:*`, `fin:*`, or storage actions are downstream extensions. They are
|
||||
valid only when the consuming system defines them and maps them to
|
||||
flex-auth resource/action semantics.
|
||||
|
||||
## Tenant Claim
|
||||
|
||||
`tenant` is required for every token accepted by profile consumers.
|
||||
|
||||
Suggested identifiers:
|
||||
|
||||
```text
|
||||
tenant:platform
|
||||
tenant:coulomb
|
||||
tenant:sandbox:<name>
|
||||
tenant:customer:<name>
|
||||
```
|
||||
|
||||
`tenant:platform` is the platform control-plane tenant. Tenant
|
||||
administration for `tenant:coulomb` or later tenants must never imply
|
||||
platform-root authority.
|
||||
|
||||
Subjects may have access to multiple tenants, but a token used for a
|
||||
request MUST identify the tenant context for that request. If a client
|
||||
needs to switch tenant context, it obtains a new token or uses an
|
||||
approved token-exchange flow that records the target tenant.
|
||||
|
||||
## Assurance Evidence
|
||||
|
||||
The canonical assurance claim is `assurance`.
|
||||
|
||||
It is an object with these fields:
|
||||
|
||||
| Field | Type | Meaning |
|
||||
| --- | --- | --- |
|
||||
| `level` | string | `aal0`, `aal1`, `aal2`, `aal3`, or `break_glass` |
|
||||
| `methods` | array | Authentication methods, e.g. `pwd`, `otp`, `webauthn`, `client_secret`, `workload_identity`, `upstream_mfa` |
|
||||
| `mfa` | boolean | Whether the authentication included multiple factors or equivalent upstream evidence |
|
||||
| `source` | string | Provider of the evidence, e.g. `key-cape`, `keycloak`, `privacyidea`, `entra`, `local-identity` |
|
||||
| `at` | number | Authentication time, recommended |
|
||||
|
||||
Level meanings:
|
||||
|
||||
| Level | Meaning |
|
||||
| --- | --- |
|
||||
| `aal0` | Local/dev or unauthenticated bootstrap evidence; never production privileged |
|
||||
| `aal1` | Single-factor or service credential evidence |
|
||||
| `aal2` | MFA or equivalent strong upstream assurance |
|
||||
| `aal3` | Phishing-resistant or hardware-backed assurance |
|
||||
| `break_glass` | Time-bounded emergency access with post-event review |
|
||||
|
||||
Privileged, destructive, platform-root, secret, credential-vending, and
|
||||
emergency flows require `aal2` or stronger unless a policy explicitly
|
||||
permits a narrower service or workload identity path. Emergency access
|
||||
MUST use `break_glass` and short token lifetimes.
|
||||
|
||||
Provider-native claims such as `acr` and `amr` may be present, but
|
||||
consumers use `assurance` as the normalized profile claim.
|
||||
|
||||
## Identity To Authorization Contract
|
||||
|
||||
flex-auth consumes IAM Profile tokens as normative identity input.
|
||||
flex-auth MUST NOT re-derive identity, tenant, group, role, or assurance
|
||||
facts from provider-specific session state.
|
||||
|
||||
The profile guarantees these inputs for authorization decision envelopes:
|
||||
|
||||
| Decision input | Source claim |
|
||||
| --- | --- |
|
||||
| Subject | `sub` |
|
||||
| Issuer | `iss` |
|
||||
| Audience | `aud` |
|
||||
| Tenant | `tenant` |
|
||||
| Principal type | `principal_type` |
|
||||
| Groups | `groups` |
|
||||
| Roles | `roles` |
|
||||
| Scopes | `scope` or `scp` |
|
||||
| Assurance | `assurance` |
|
||||
| Authorized client | `azp` or `client_id`, where present |
|
||||
| Agent/delegation context | `agent`, `actor_sub`, or `act`, where present |
|
||||
| Token lifetime/audit ids | `iat`, `nbf`, `exp`, `jti`, where present |
|
||||
|
||||
Authorization decisions are made by flex-auth and its delegated PDP
|
||||
adapters. Identity providers may assert roles or scopes, but those claims
|
||||
are inputs to policy, not final permission to act on a resource.
|
||||
|
||||
## Token Lifecycle
|
||||
|
||||
Recommended production defaults:
|
||||
|
||||
| Token | Lifetime | Notes |
|
||||
| --- | --- | --- |
|
||||
| Human access token | 5-15 minutes | Short-lived bearer token |
|
||||
| Refresh token | 8-12 hours | Rotated and revoked on logout or suspicion |
|
||||
| Service token | 5-30 minutes | Reissued by client credentials or workload identity |
|
||||
| Agent token | 5-30 minutes | Shorter when delegated or platform-scoped |
|
||||
| Emergency token | 5-15 minutes | Requires incident/review record |
|
||||
|
||||
Consumers MUST reject expired tokens and tokens with invalid issuer,
|
||||
audience, signature, `nbf`, or algorithm. Clock skew tolerance SHOULD be
|
||||
small, normally no more than 60 seconds.
|
||||
|
||||
JWKS material may be cached, but consumers MUST tolerate key rotation by
|
||||
refreshing JWKS when a token uses an unknown `kid`.
|
||||
|
||||
## Local Development Profile
|
||||
|
||||
A local file-backed provider may be used for development, tests, and
|
||||
bootstrap contexts where the full platform is unavailable.
|
||||
|
||||
It MUST:
|
||||
|
||||
- expose OIDC discovery;
|
||||
- issue signed JWTs;
|
||||
- support deterministic test users and service accounts;
|
||||
- use local-only issuer URLs or a clearly local issuer identifier;
|
||||
- mark tokens as local/development through issuer, audience, or
|
||||
assurance evidence;
|
||||
- be rejected by production consumers.
|
||||
|
||||
Production consumers MUST reject:
|
||||
|
||||
- issuer `local-identity`;
|
||||
- `http://` issuers;
|
||||
- loopback issuers such as `localhost` or `127.0.0.1`;
|
||||
- tokens with `assurance.level: aal0`;
|
||||
- tokens where the environment marks the issuer as local/dev.
|
||||
|
||||
## Emergency And Break-Glass Access
|
||||
|
||||
Emergency access is allowed only as a break-glass path.
|
||||
|
||||
Requirements:
|
||||
|
||||
- Emergency identities are disabled by default.
|
||||
- Activation requires an incident, decision, or human-recorded review
|
||||
reference.
|
||||
- Tokens are short-lived and carry the `emergency` role.
|
||||
- Tokens carry `assurance.level: break_glass`.
|
||||
- Every emergency action emits an audit/progress/incident event.
|
||||
- Emergency access is reviewed after use and then disabled again.
|
||||
|
||||
Emergency access MUST NOT bypass audit logging or flex-auth policy.
|
||||
|
||||
## Conformance
|
||||
|
||||
An implementation conforms to IAM Profile v0.2 when it passes the
|
||||
executable conformance suite in:
|
||||
|
||||
```text
|
||||
tools/iam-profile-conformance/
|
||||
```
|
||||
|
||||
The suite validates:
|
||||
|
||||
- discovery document completeness;
|
||||
- PKCE `S256` advertisement and rejection of authorization requests that
|
||||
omit a code challenge;
|
||||
- JWKS structure and key ids;
|
||||
- token issuer, audience, expiry, `nbf`, `iat`, and RS256 signature;
|
||||
- tenant, principal type, groups, roles, scopes, and assurance claim
|
||||
shape;
|
||||
- agent and delegated-agent claim shape;
|
||||
- local-development issuer rejection in production mode.
|
||||
|
||||
Conformance must be runnable against both key-cape lightweight issuers
|
||||
and Keycloak expanded-mode issuers. Implementations may add provider
|
||||
adapters, but the token consumed by applications and flex-auth must match
|
||||
the core claim contract above.
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
A service or implementation is profile-ready when:
|
||||
|
||||
- it reads OIDC discovery rather than hardcoding endpoints;
|
||||
- it validates issuer, audience, expiry, `nbf`, algorithm, and
|
||||
signature;
|
||||
- it refreshes JWKS on unknown `kid`;
|
||||
- it supports Authorization Code + PKCE for human login;
|
||||
- it supports service-account or workload identity tokens;
|
||||
- it emits `tenant`, `principal_type`, `groups`, `roles`,
|
||||
`scope`/`scp`, and `assurance`;
|
||||
- it maps provider-native claims into the canonical core claims;
|
||||
- it rejects local-development issuers in production;
|
||||
- it logs emergency access with a durable audit trail;
|
||||
- flex-auth receives identity facts from the profile, not from
|
||||
provider-specific sessions.
|
||||
Reference in New Issue
Block a user