Reconcile infrastructure workplans and retire stale flex-auth references

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e77d-47a4-7771-8e34-7339c7fac0e4
This commit is contained in:
tegwick 2026-09-28 12:40:03 +02:00
parent 019e8f21a7
commit 9383b94019
12 changed files with 494 additions and 149 deletions

View file

@ -9,7 +9,7 @@ flavor: implementation
owner: worsch
topic_slug: netkingdom
created: "2026-05-20"
updated: "2026-07-08"
updated: "2026-09-28"
state_hub_workstream_id: "1075448f-d533-5f9e-94b7-c3adfe151a07"
depends_on:
- NK-WP-0003
@ -53,10 +53,10 @@ 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 |
| PostgreSQL built from scratch | CloudNativePG running on RAILIANCE01 (NK-WP-0003) | Admit a database consumer through current platform owners; prove backup/restore |
| 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 |
| Single-tenant Coulomb deployment | Recursive `tenant:platform` vs `tenant:coulomb` model (NK-WP-0006) | Evaluate 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
@ -68,7 +68,7 @@ Keycloak as the internal user store. None of those assumptions hold now:
└──────────────┼──────────────┘
▼
[ Keycloak ] expanded-mode broker
│ realm-per-tenant; IAM Profile issuer
│ realm-per-tenant candidate; IAM Profile issuer
│ secrets ← OpenBao (ESO)
│ MFA ← privacyIDEA *or* upstream assurance
▼
@ -77,7 +77,7 @@ Keycloak as the internal user store. None of those assumptions hold now:
├──► applications (depend on the Profile, not the provider)
└──► flex-auth / Topaz ── authorization decision (PDP)
coexists with: KeyCape lightweight issuer (id.coulomb.social)
coexists with: KeyCape lightweight issuer (kc.coulomb.social)
```
Keycloak answers identity (who, how authenticated, coarse claims,
@ -90,10 +90,10 @@ OpenBao.
In scope:
- decision record for expanded-mode adoption: trigger, federation
topology (broker vs SAML SP), realm-per-tenant model, and coexistence
topology (broker vs SAML SP), realm isolation model, and coexistence
with the KeyCape lightweight issuer
- custom Keycloak image (privacyIDEA provider JAR if MFA is delegated to
privacyIDEA) and Helm deployment on RAILIANCE01
- owner-packaged Keycloak image (privacyIDEA provider JAR only if selected
and verified compatible) and managed deployment on railiance01
- upstream federation: Entra ID (OIDC), AD (LDAP), generic SAML 2.0 IdP
- claim mapping to the NetKingdom IAM Profile (issuer, audience, subject,
groups, tenant, assurance evidence) and IAM Profile conformance checks
@ -112,7 +112,7 @@ Out of scope:
- tenant-specific federation policy for tenants beyond `tenant:platform`
and `tenant:coulomb`
## Tasks
## Decide federation adoption and topology
```task
id: NK-WP-0011-T01
@ -125,11 +125,14 @@ priority: high
an ADR (ADR-0009) capturing: the concrete trigger for switching a tenant
from lightweight to expanded mode; whether Keycloak acts as an OIDC
identity broker, a SAML service provider, or both; the realm-per-tenant
mapping onto `tenant:platform` / `tenant:coulomb`; how the Keycloak issuer
coexists with the KeyCape issuer (`id.coulomb.social`) so applications
candidate and its alternatives mapped onto `tenant:platform` /
`tenant:coulomb`; how the Keycloak issuer
coexists with the KeyCape issuer (`kc.coulomb.social`) so applications
still target one IAM Profile contract; and the canonical hostname/issuer
for the broker. Resolve or supersede D2 from NK-WP-0001.
## Admit the database consumer
```task
id: NK-WP-0011-T02
state_hub_task_id: "2fe6f100-3a5d-563e-b033-7d7b846ae487"
@ -137,12 +140,15 @@ status: todo
priority: high
```
**PostgreSQL `keycloak_db` on the existing operator.** Add a `keycloak`
database and role to the CloudNativePG instance from NK-WP-0003 (do not
deploy a new database). Source credentials from OpenBao via ESO into a K8s
Secret. Confirm the existing backup schedule covers the new database and
**PostgreSQL `keycloak_db` on the existing operator.** Have railiance-platform
and rapp-postgres admit a named Keycloak database consumer against the current
database catalog and isolation needs. Do not assume the historical NK-WP-0003
instance is the correct placement. Source credentials from OpenBao via ESO
into a K8s Secret. Confirm the existing backup schedule covers the new database and
run a restore drill for `keycloak_db` specifically.
## Package the broker deployment
```task
id: NK-WP-0011-T03
state_hub_task_id: "32d1411b-10a4-5a8b-8f43-99ac46d83908"
@ -152,12 +158,15 @@ priority: high
**Deploy expanded-mode Keycloak.** Build a custom image
(`kc.sh build`, privacyIDEA provider JAR included only if T5 delegates MFA
to privacyIDEA). Deploy via plain Helm on RAILIANCE01 behind Traefik +
to privacyIDEA). Assign the package/runtime owner under ADR-0015 and deploy
through its managed declaration on railiance01 behind Traefik +
cert-manager at the issuer hostname from T1. Admin bootstrap secret and DB
secret come from OpenBao/ESO — never typed, never in git. Hostname
strictness + proxy headers configured for Traefik. Realm import is
GitOps-friendly (realm JSON/CR in git).
## Integrate an upstream identity provider
```task
id: NK-WP-0011-T04
state_hub_task_id: "6697a994-7343-5ea8-8b37-bc3b921e5a9b"
@ -172,6 +181,8 @@ audience, subject, groups, **tenant**, and assurance evidence. Define the
attribute/claim mappers and group→role mapping. Verify a federated login
end-to-end for at least the Entra ID path.
## Define federated assurance
```task
id: NK-WP-0011-T05
state_hub_task_id: "d845380d-3dbc-5e59-8f2b-5a4d1b32d89d"
@ -187,6 +198,8 @@ evidence in the token. Require step-up for admin console and
platform-root-sensitive clients. Ensure assurance evidence is carried in
the IAM Profile token so flex-auth can gate privileged actions on it.
## Verify IAM conformance and coexistence
```task
id: NK-WP-0011-T06
state_hub_task_id: "9cb7fd93-c16e-5102-83ce-195b3aa87446"
@ -199,9 +212,11 @@ conformance checks against the Keycloak issuer (discovery document, PKCE,
token/claim shape, JWKS, userinfo). Verify an application configured for
the IAM Profile can authenticate against either the KeyCape or the
Keycloak issuer per the T1 selection rule. Use the canonical
`canon/standards/iam-profile_v0.2.md` contract and the executable suite in
`canon/standards/iam-profile_v0.3.md` contract and the executable suite in
`tools/iam-profile-conformance/`. Document per-tenant issuer selection.
## Enforce tenant and platform boundaries
```task
id: NK-WP-0011-T07
state_hub_task_id: "38998c68-29bf-50d2-8c8d-0c75184d5833"
@ -209,14 +224,17 @@ status: todo
priority: high
```
**Recursive tenancy & authorization boundary.** Implement realm-per-tenant
with platform-root guardrails: tenant admins manage only their realm and
**Recursive tenancy & authorization boundary.** Implement T1's reviewed
realm/tenant topology with platform-root guardrails. If realm-per-tenant is
selected, tenant admins manage only their realm; in every topology they
must not be able to alter IAM Profile semantics, the platform realm,
federation trust, OpenBao platform mounts, or audit retention (per the
flex-auth/Topaz implications in the architecture doc). Confirm flex-auth +
Topaz remains the PDP; if a Keycloak Authorization Services adapter is
used at all, document it as a delegated, non-canonical adapter.
## Prove recovery and audit delivery
```task
id: NK-WP-0011-T08
state_hub_task_id: "e5f44ddc-9645-5f61-b84c-da5ab9cccb6d"
@ -224,8 +242,9 @@ status: todo
priority: medium
```
**Backups, DR, break-glass, monitoring, audit.** Realm exports to git; DB
backup + restore drill (T2); break-glass admin path disabled-by-default
**Backups, DR, break-glass, monitoring, audit.** Only sanitized declarative
realm configuration belongs in git; keep credential-bearing exports in
protected backup custody; DB backup + restore drill (T2); break-glass admin path disabled-by-default
with alerting on use; Prometheus/Grafana for auth success/failure, MFA
latency, federation errors. Ship Keycloak events to the durable platform
audit sink alongside flex-auth/Topaz/OpenBao records, with correlation
@ -235,7 +254,7 @@ production-readiness checklist.
## Acceptance Criteria
- An ADR records the expanded-mode trigger, federation topology,
realm-per-tenant model, and KeyCape/Keycloak issuer coexistence.
selected realm/tenant isolation model, and KeyCape/Keycloak issuer coexistence.
- A federated user from at least one enterprise IdP (Entra ID) can log in
and receive an IAM Profile-conformant token with tenant + assurance
claims.
@ -257,5 +276,25 @@ production-readiness checklist.
- **railiance-platform**: OpenBao must expose a Keycloak auth role / ESO
path before T3; unseal/break-glass story must be ready.
- **IAM Profile spec**: resolved by NK-WP-0012. T6 consumes
`canon/standards/iam-profile_v0.2.md` and
`canon/standards/iam-profile_v0.3.md` and
`tools/iam-profile-conformance/`.
## Infrastructure review — 2026-09-28
Keep in backlog until a named enterprise tenant, upstream IdP owner and
concrete federation need justify operating another issuer. No Keycloak
Deployment appears in today's cluster inventory. Realm-per-tenant remains a
proposal to evaluate in T01, not a requirement derived from current topology;
prove its mapping to tenant-engine's canonical identity/lifecycle contract.
The live issuer is `https://kc.coulomb.social`; IAM v0.3 is accepted and v0.4
step-up is proposed. T01/T05/T06 must coordinate with NK-WP-0042 and preserve
existing issuer/subject account bindings, audiences and session/revocation
behavior. Do not infer equivalent assurance from an upstream MFA claim without
a reviewed trust mapping. The single-node cluster and single-instance database
providers offer no automatic HA guarantee. T02/T08 must name backup ownership,
off-host custody and an isolated restore proof. OpenBao access is private via
the platform operator path. Resource placement, packaging and runtime
execution belong to their owners, not this canon repository.
Evidence and cross-plan priorities: [estate review](../history/2026-09-28-open-workplan-infrastructure-review.md).