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
This commit is contained in:
parent
5c4bc16706
commit
0d460e3c02
11 changed files with 469 additions and 8 deletions
111
docs/adr/ADR-0009-expanded-mode-keycloak-federation-topology.md
Normal file
111
docs/adr/ADR-0009-expanded-mode-keycloak-federation-topology.md
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
---
|
||||
id: NK-ADR-0009
|
||||
type: architecture-decision-record
|
||||
title: "Expanded-Mode Keycloak: Adoption Trigger and Federation Topology"
|
||||
status: proposed
|
||||
owner: net-kingdom
|
||||
revision: "1"
|
||||
proposed: "2026-09-28"
|
||||
last_reviewed: "2026-09-28"
|
||||
review_interval: 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?
|
||||
Loading…
Add table
Add a link
Reference in a new issue