> Extracted from NK-WP-0001 (T05–T08, the deferred Keycloak path) and
> refined against where net-kingdom actually stands today: a deployed
> KeyCape lightweight stack, an OpenBao runtime-secret authority, and a
> recursive platform/tenant authorization model. This is **expanded
> identity mode** in the architecture (`docs/platform-identity-security-architecture.md`).
## Goal
Stand up **Keycloak as an identity broker** that federates upstream
enterprise identity providers (Microsoft Entra ID / Azure AD via OIDC,
on-prem Active Directory via LDAP, and generic SAML 2.0 IdPs) and issues
**NetKingdom IAM Profile-conformant** tokens downstream — without
displacing flex-auth as the authorization decision point or breaking the
recursive platform/tenant boundary.
This is the answer to the long-standing open question
*"when does the platform switch from key-cape lightweight mode to Keycloak
expanded mode?"* — expanded mode exists **specifically** to onboard
identities that originate in an external enterprise IdP, which the
lightweight Authelia + LLDAP stack cannot broker.
## Why this is not just "resume NK-WP-0001"
NK-WP-0001 assumed a greenfield: bootstrap Vault, build PostgreSQL, treat
Keycloak as the internal user store. None of those assumptions hold now:
| NK-WP-0001 assumption | Current reality | Effect on this plan |
|---|---|---|
| HashiCorp Vault, bootstrapped from KeePassXC | **OpenBao** is the runtime secret authority (NK-WP-0006); SOPS/age + agent bootstrap exist (NK-WP-0004/0005) | Keycloak DB + admin secrets come from OpenBao via ESO; no new vault bootstrap |
| PostgreSQL built from scratch | CloudNativePG running on RAILIANCE01 (NK-WP-0003) | Add `keycloak_db` to the existing operator, reuse backup pattern |
| Keycloak is the internal source of truth (D2 hybrid) | KeyCape lightweight stack is the *deployed* IAM Profile issuer | Keycloak is a **broker/federation front-end**, not the primary user store |
| Authorization via Keycloak Authorization Services | flex-auth + Topaz is the canonical PDP (ADR-0006) | Keycloak AuthZ Services is at most an optional adapter, never canonical |
| Single-tenant Coulomb deployment | Recursive `tenant:platform` vs `tenant:coulomb` model (NK-WP-0006) | Realm-per-tenant; tenant admins must not receive platform-root |
| MFA solely via privacyIDEA provider JAR | privacyIDEA deployed *and* upstream IdPs carry their own MFA | MFA assurance source becomes a decision, not a default |
## Architecture
```text
Enterprise IdPs (upstream)
Entra ID (OIDC) AD (LDAP) SAML 2.0 IdP
│ │ │
└──────────────┼──────────────┘
▼
[ Keycloak ] expanded-mode broker
│ realm-per-tenant; IAM Profile issuer
│ secrets ← OpenBao (ESO)
│ MFA ← privacyIDEA *or* upstream assurance
▼
NetKingdom IAM Profile token (OIDC/PKCE)
│
├──► applications (depend on the Profile, not the provider)