net-kingdom/docs/adr/ADR-0009-expanded-mode-keycloak-federation-topology.md
tegwick 0d460e3c02
Some checks are pending
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
Activate NK-WP-0009/0011; add tutorials slice and proposed ADR-0009
- docs/tutorials: template, OpenBao and SSH tutorials (unexercised)
- tools/tutorial-verify + make tutorials-verify (NK-WP-0009-T06)
- ADR-0009 proposed: expanded-mode Keycloak trigger and topology

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: sonnet
Assistant-Process: 295952@bnt-lap001
Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
2026-09-28 23:31:48 +02:00

5.7 KiB

id type title status owner revision proposed last_reviewed review_interval
NK-ADR-0009 architecture-decision-record Expanded-Mode Keycloak: Adoption Trigger and Federation Topology proposed net-kingdom 1 2026-09-28 2026-09-28 12m

ADR-0009 - Expanded-Mode Keycloak: Adoption Trigger and Federation Topology

Status: Proposed (awaiting Bernd's decision; NK-WP-0011-T01) Date: 2026-09-28 Deciders: Bernd Worsch, Claude

Context

The live IAM Profile issuer is KeyCape (Authelia + LLDAP + privacyIDEA) at https://kc.coulomb.social. No Keycloak Deployment exists. The architecture doc says expanded mode is capability-driven, chiefly inbound enterprise federation (Entra ID, AD, SAML), and leaves the per-tenant trigger and dual-issuer rule open. ADR-0014 defines the IAM capability role as a tenant operating its own dedicated IAM instance. ADR-0006 keeps flex-auth as the PDP. ADR-0016 makes MFA a user preference with workload opt-in step-up. The user-engine extension-point doc requires immutable provider subjects, tenant-scoped group mappings, and no privilege from unmapped upstream claims. The estate is one node with single-instance databases, so no option here buys HA.

NK-WP-0001 decision D2 (Keycloak as primary internal user store) predates all of this.

Decision (proposed)

  1. Trigger. A tenant moves to expanded mode only when all three hold: a named tenant, a named owner of the upstream IdP, and a concrete federation requirement the lightweight stack cannot meet. User count, or the wish to have Keycloak, is not a trigger. Until then NK-WP-0011 implementation tasks stay unstarted.
  2. Role: OIDC identity broker only. Keycloak brokers upstream Entra ID (OIDC), AD (LDAP federation) and generic SAML 2.0 IdPs (SAML as an upstream, via Keycloak's identity-provider brokering). Downstream it issues only IAM Profile OIDC/PKCE tokens. Emitting SAML assertions to downstream applications is out of scope. Keycloak is not the primary user store (supersedes D2), not the PDP, and not a secret store.
  3. Isolation. Realms are the tenant boundary. The tenant:platform realm is separate and reserved. A tenant without the IAM role gets a realm in the shared broker; a tenant with the IAM role gets a dedicated broker instance (ADR-0014). A shared broker gives realm-level, not process-level, isolation, so it is acceptable only for tenants whose federation trust and data classification allow that. Realm admins may not alter IAM Profile semantics, the platform realm, federation trust settings, or audit retention. tenant-engine, not Keycloak, is the source of truth for tenant existence and capability roles.
  4. Coexistence. Each tenant has exactly one active issuer at a time, recorded by tenant-engine and published as issuer configuration. KeyCape stays unchanged and keeps serving lightweight tenants. Applications target the IAM Profile and discover the issuer; they do not embed provider choice. Account bindings remain keyed on issuer plus immutable subject, so moving a tenant between issuers is a planned migration with an explicit subject-mapping step, never a silent dual login.
  5. Assurance. Federated login is AAL1 by default. Upstream MFA (for example Entra Conditional Access) counts as higher assurance only through a reviewed, per-IdP trust mapping written down before use. Privileged step-up continues to use privacyIDEA under ADR-0016 and the proposed IAM v0.4 step-up. The privacyIDEA provider JAR is added only if a tenant needs Keycloak-side MFA.
  6. Provisioning and mapping. Follow the user-engine extension-point rules: JIT creates a pending projection; group mappings are tenant-scoped, versioned and deny ambiguous envelopes; no platform role from raw upstream group names.
  7. Hostname and issuer. Not chosen here. It is assigned by the package owner under ADR-0015 with the first tenant, as a distinct host from kc.coulomb.social; the issuer URL is then treated as immutable.
  8. Ownership. net-kingdom owns this contract and conformance checks. Packaging and runtime belong to the ADR-0015 owner; the database consumer to railiance-platform; OpenBao roles to railiance-platform.

Alternatives considered

  • Keycloak replaces KeyCape. Rejected: unnecessary migration risk for working tenants; contradicts capability-driven adoption.
  • Dedicated instance for every federated tenant. Strongest isolation, but on one node the cost is multiplied database, memory and patching for tenants that do not need it. Kept for IAM-role tenants.
  • Realm-per-tenant only, including IAM tenants. Contradicts ADR-0014's meaning of IAM.
  • Keycloak as SAML IdP downstream too. No consumer requires it; widens the contract surface. Revisit on a named need.
  • Trust upstream MFA claims by default. Rejected: assurance would depend on each customer's tenant configuration.
  • Build ahead of demand. Rejected: adds an issuer, a database and a break-glass path with no owner or user.

Consequences

  • NK-WP-0011 T02 onward stay gated on the trigger in decision 1.
  • T06 conformance uses tools/iam-profile-conformance/ against IAM v0.3.
  • tenant-engine needs an issuer-per-tenant field; this is a dependency to raise with its owner, not something built here.
  • Shared-broker realms cannot be described as strongly isolated tenants.
  • No HA is implied; T02 and T08 must name backup ownership, off-host custody and an isolated restore proof.

Open questions

  • Which named tenant and IdP owner will trigger the first deployment?
  • Does key-cape require changes for issuer-per-tenant discovery (EP-NK-001)?
  • Which claim carries the federated-assurance mapping so flex-auth can consume it?