14 KiB
id, type, title, domain, status, version, created, updated, scope, supersedes, adr
| id | type | title | domain | status | version | created | updated | scope | supersedes | adr | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| netkingdom-iam-profile | standard | NetKingdom IAM Profile v0.2 | netkingdom | accepted | 0.2 | 2026-05-22 | 2026-05-22 | core-platform |
|
|
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:platformis distinct from tenant planes such astenant: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:
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
S256is 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
agentobject withidandmode. agent.modeisautonomousordelegated.- Delegated agents MUST identify the delegating actor using
actor_subor an equivalentact.subclaim. - 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:
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
localhostor127.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
emergencyrole. - 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:
tools/iam-profile-conformance/
The suite validates:
- discovery document completeness;
- PKCE
S256advertisement 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, andassurance; - 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.