generated from coulomb/repo-seed
Archive closed workplans to workplans/archived/ (ADR-001)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
38
workplans/archived/260702-ADHOC-2026-06-14.md
Normal file
38
workplans/archived/260702-ADHOC-2026-06-14.md
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
id: ADHOC-2026-06-14
|
||||
type: workplan
|
||||
title: "Ad hoc NetKingdom operator usability fixes"
|
||||
domain: netkingdom
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
created: "2026-06-14"
|
||||
updated: "2026-06-14"
|
||||
state_hub_workstream_id: "c6f3d6bf-4916-490d-96ce-092d2776d7e7"
|
||||
---
|
||||
|
||||
# Ad hoc NetKingdom operator usability fixes
|
||||
|
||||
## SOPS Custody Unlock Helper
|
||||
|
||||
```task
|
||||
id: ADHOC-2026-06-14-T01
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "bb5973d8-8e61-48f6-b627-a662f8a34ad1"
|
||||
```
|
||||
|
||||
Added a custody unlock helper for SOPS/age operations so drills and incident
|
||||
commands can use the password-safe/offline custody age private key without
|
||||
installing it permanently on a workstation.
|
||||
|
||||
The helper validates the supplied private key against the expected public age
|
||||
recipient, writes a temporary `0600` `SOPS_AGE_KEY_FILE`, runs the requested
|
||||
command or opens an incident shell, and removes the temporary key on exit.
|
||||
|
||||
Documented the inter-hub recovery-drill path:
|
||||
|
||||
```bash
|
||||
make sops-custody-run COMMAND='make -C /home/worsch/inter-hub recovery-drill'
|
||||
```
|
||||
@@ -0,0 +1,450 @@
|
||||
---
|
||||
id: NET-WP-0017
|
||||
type: workplan
|
||||
title: "IT Security Readiness For User Onboarding"
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
created: "2026-05-26"
|
||||
updated: "2026-06-03"
|
||||
depends_on:
|
||||
- NET-WP-0015
|
||||
- NET-WP-0016
|
||||
- RAIL-PL-WP-0002
|
||||
state_hub_workstream_id: "385de708-fd59-4bab-a4f4-28c1c476b3ea"
|
||||
---
|
||||
|
||||
# NET-WP-0017 - IT Security Readiness For User Onboarding
|
||||
|
||||
## Goal
|
||||
|
||||
Finish the remaining NetKingdom and Railiance security setup needed before
|
||||
ordinary platform users, tenant admins, or fabric admins are onboarded.
|
||||
|
||||
`NET-WP-0015` established the king credential, OpenBao bootstrap ceremony, and
|
||||
guided control surface. This workplan is the narrower finish-line plan: routine
|
||||
admin access must use NetKingdom identity, bootstrap-era material must be
|
||||
retired or explicitly accepted, audit/recovery posture must be credible, and a
|
||||
first non-root onboarding dry run must prove the lifecycle model.
|
||||
|
||||
## Current Evidence
|
||||
|
||||
- `platform-root` exists in LLDAP, belongs to `net-kingdom-admins`, has MFA,
|
||||
and completed KeyCape OIDC login.
|
||||
- Railiance OpenBao is initialized, unsealed, and post-unseal verified.
|
||||
- OpenBao initial configuration was applied; `platform/` KV and Kubernetes auth
|
||||
exist.
|
||||
- The initial OpenBao root token is recorded as revoked.
|
||||
- Trial unseal shares were rotated.
|
||||
- The KeyCape `openbao-admin` client is live and verified, including the public
|
||||
`https://kc.coulomb.social` route and certificate.
|
||||
- OpenBao OIDC auth configuration is applied; MFA-backed OpenBao admin login
|
||||
completed successfully and the resulting token lookup showed the
|
||||
`platform-admin` policy for `platform-root`.
|
||||
- Declarative local OpenBao audit and authenticated audit visibility are
|
||||
complete; enterprise durable tenant-aware audit retention has been split into
|
||||
the standalone `audit-core` product. Residual taint closeout,
|
||||
cleanup/rotation, and the first ordinary-user onboarding dry run are still
|
||||
pending.
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 - Finish OIDC-Backed OpenBao Admin Login
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "9b087bbd-631b-4316-b94d-a8265a05b065"
|
||||
```
|
||||
|
||||
Run the fixed OpenBao OIDC helper, record the non-secret completion flag, then
|
||||
verify `platform-root` can complete:
|
||||
|
||||
```bash
|
||||
bao login -method=oidc -path=keycape role=platform-admin
|
||||
```
|
||||
|
||||
The verification must prove the resulting OpenBao token has the intended
|
||||
`platform-admin` policy without relying on the initial root token or a manually
|
||||
minted temporary operator token.
|
||||
|
||||
**2026-05-29:** DNS and ACME issuance for `kc.coulomb.social` are healthy:
|
||||
cert-manager issued `kc-tls`, and `sso-mfa/k8s/keycape/verify-openbao-client.sh`
|
||||
passes against the live KeyCape route. `configure-openbao-oidc.sh` has applied
|
||||
the OpenBao `auth/keycape` OIDC configuration and `platform-admin` role. The
|
||||
remaining T01 gate is the human browser login with MFA and a token lookup that
|
||||
shows the expected OpenBao `platform-admin` policy.
|
||||
|
||||
**2026-06-01:** Added a guided console recovery action for the observed
|
||||
privacyIDEA state-loss blocker: if the live instance lacks the `coulomb` realm,
|
||||
LLDAP resolver, or self-service policies, the operator can run **Repair
|
||||
privacyIDEA realm and self-service** from **Usecases & Runbooks**. The action
|
||||
does not store secrets; it calls `repair-realm-live.sh`, prompts live, creates
|
||||
temporary env files for `bootstrap-realm.sh`, removes them on exit, and then
|
||||
runs `verify-t06.sh`. After repair, `platform-root` TOTP
|
||||
enrollment/re-enrollment and the MFA-backed `bao login` proof are still
|
||||
required.
|
||||
|
||||
**2026-06-01:** Fixed the follow-up OpenBao OIDC token exchange
|
||||
`user not found` error caused by live `keycape-config` drift: the Secret had
|
||||
lost the non-secret LLDAP lookup fields `userOU: ou=people` and
|
||||
`groupOU: ou=groups`. The KeyCape live patch helper now enforces those fields
|
||||
alongside the `openbao-admin` client, the live Secret was patched, KeyCape was
|
||||
restarted, and `verify-openbao-client.sh` passes again.
|
||||
|
||||
**2026-06-01:** Deployed a KeyCape runtime lookup fix for the remaining
|
||||
`user not found` token-exchange failure after config drift was ruled out. The
|
||||
LDAP adapter now treats provisioning metadata validation failures as runtime
|
||||
warnings instead of blocking token issuance for an otherwise resolved LLDAP
|
||||
user. The patched image `main-runtime-lookup-0601` is live and
|
||||
`verify-openbao-client.sh` passes after rollout.
|
||||
|
||||
**2026-06-01:** Deployed the follow-up KeyCape OIDC nonce fix after OpenBao
|
||||
rejected the exchanged ID token with `invalid id_token nonce`. KeyCape now
|
||||
persists the original authorization `nonce` through pending state and the
|
||||
authorization-code session, then emits it in the ID token. The patched image
|
||||
`main-nonce-0601` is live, reports 1/1 ready, and `verify-openbao-client.sh`
|
||||
passes after rollout.
|
||||
|
||||
**2026-06-01:** Fixed the next OpenBao role configuration failure,
|
||||
`error converting claim 'groups' to string`. KeyCape correctly emits `groups`
|
||||
as an array for `groups_claim`; OpenBao only failed because the role also copied
|
||||
that array through scalar `claim_mappings`. The helper now leaves groups in
|
||||
`groups_claim`/`bound_claims` and maps only scalar `email` and
|
||||
`preferred_username` metadata.
|
||||
|
||||
**2026-06-01:** The operator reached the OpenBao success page, "Signed in via
|
||||
your OIDC provider", after reapplying the corrected role. The follow-up
|
||||
terminal proof showed `token_policies`/`policies` containing `platform-admin`,
|
||||
`token_meta_role: platform-admin`, and `token_meta_username: platform-root`.
|
||||
T01 is closed; the pasted short-lived token should be treated as disclosed and
|
||||
revoked or allowed to expire after the check.
|
||||
|
||||
### T02 - Close OpenBao Audit And Recovery Production Gates
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "909944bd-843a-4a63-8c87-536cea052a88"
|
||||
```
|
||||
|
||||
Resolve the remaining OpenBao production-trust gates:
|
||||
|
||||
- configure audit declaratively if API-managed audit remains rejected;
|
||||
- record the interim Audit Core interface used before enterprise durable audit
|
||||
retention is implemented;
|
||||
- hand off durable tenant-aware audit shipping beyond the audit PVC to
|
||||
`audit-core`;
|
||||
- retain non-secret restore-drill evidence and repeat the drill if any
|
||||
material changed;
|
||||
- record emergency seal/unseal drill evidence; and
|
||||
- identify the next independent escrow holder for moving beyond temporary
|
||||
single-king custody.
|
||||
|
||||
**2026-06-01:** Started the OpenBao audit/recovery closeout. Railiance source
|
||||
now has a declarative OpenBao file-audit stanza in
|
||||
`helm/openbao-values.yaml`, and its initial-config helper now verifies
|
||||
`bao audit list` instead of trying to create audit devices through the API.
|
||||
The Railiance post-unseal verifier also warns when
|
||||
`/openbao/audit/openbao-audit.log` is missing or empty. Live non-secret
|
||||
checks still show OpenBao healthy and unsealed with Bound data/audit PVCs, but
|
||||
the live Helm values do not yet include the declarative audit stanza and the
|
||||
audit directory is empty. Do not move production secrets into OpenBao until a
|
||||
planned Helm rollout is performed with unseal shares available, `file/` audit
|
||||
is visible, an audit log is written, durable audit shipping beyond the PVC is
|
||||
selected, and restore/emergency drill evidence plus a next escrow holder are
|
||||
recorded.
|
||||
|
||||
**2026-06-01:** Completed the attended live rollout of the Railiance
|
||||
declarative file-audit configuration. The Helm release was upgraded, the
|
||||
`OnDelete` StatefulSet pod was deliberately recycled, the operator unsealed the
|
||||
new pod, and `make openbao-verify-post-unseal` now reports OpenBao `2.5.4`,
|
||||
`Sealed: false`, an audit directory, and a non-empty
|
||||
`/openbao/audit/openbao-audit.log`. The Railiance source now pins the live
|
||||
OpenBao image tag to `2.5.4` after the chart upgrade advanced the runtime from
|
||||
`2.5.3`; a follow-up Helm revision 3 applied the explicit tag while the pod
|
||||
remained ready. T02 remains open for the authenticated `bao audit list` proof,
|
||||
durable audit shipping beyond the audit PVC, restore-drill evidence, emergency
|
||||
seal/unseal drill evidence, and the next independent escrow holder.
|
||||
|
||||
**2026-06-01:** Added a Railiance evidence-only helper for the authenticated
|
||||
OpenBao proof: `make openbao-verify-authenticated` prompts for an approved
|
||||
OpenBao token without echoing it and verifies `file/` audit visibility,
|
||||
`platform/` secrets, `kubernetes/` auth, `keycape/` auth, and a non-empty audit
|
||||
log without mutating OpenBao configuration. The helper can also reuse a
|
||||
still-valid pod token helper with
|
||||
`OPENBAO_VERIFY_AUTH_ARGS=--use-token-helper`, avoiding token movement through
|
||||
the local shell. It is ready to run with the MFA-backed
|
||||
`platform-root`/`platform-admin` path. Durable audit shipping remains open; the
|
||||
audit PVC is not a durable sink and non-secret evidence hashes or State Hub
|
||||
notes are not substitutes for retained audit log custody.
|
||||
|
||||
**2026-06-01:** Completed the authenticated OpenBao proof through the
|
||||
MFA-backed KeyCape path without printing token material. A fresh
|
||||
`bao login -no-print -method=oidc -path=keycape role=platform-admin` browser
|
||||
flow cached the pod token helper, then `make openbao-verify-authenticated
|
||||
OPENBAO_VERIFY_AUTH_ARGS=--use-token-helper` passed. Evidence: OpenBao is
|
||||
unsealed on `2.5.4`, `file/` audit is visible, `platform/` secrets are visible,
|
||||
`kubernetes/` and `keycape/` auth methods are visible, and the audit log grew
|
||||
from 7969 bytes to 23330 bytes during the check. The cached verifier token was
|
||||
then revoked with `bao token revoke -self`. T02 remains open for durable audit
|
||||
shipping beyond the audit PVC, restore-drill evidence, emergency seal/unseal
|
||||
drill evidence, and the next independent escrow holder.
|
||||
|
||||
**2026-06-01:** Split enterprise audit retention out of this task and into the
|
||||
new standalone `/home/worsch/audit-core` repo. `audit-core` now has
|
||||
`INTENT.md`, a product requirements definition, and a minimal replaceable mock
|
||||
backend that writes JSONL audit events to
|
||||
`/tmp/audit-core/audit-YYYYMMDDTHH.jsonl` and cleans up files older than seven
|
||||
days. A smoke event for the OpenBao authenticated readiness proof was written
|
||||
through the mock interface, and `audit-core` tests pass. This mock backend is
|
||||
acceptable for bootstrap/development wiring and NetKingdom UI integration, but
|
||||
it is not durable audit custody and must not be presented as enterprise
|
||||
retention. NET-WP-0017-T02 now treats the full tenant-aware durable audit
|
||||
fabric as an `audit-core` follow-up rather than an OpenBao bootstrap subtask.
|
||||
Remaining T02 gates are restore-drill evidence, emergency seal/unseal drill
|
||||
evidence, the next independent escrow holder, and an explicit risk note if
|
||||
ordinary onboarding proceeds before the production Audit Core sink exists.
|
||||
|
||||
**2026-06-01:** Tightened the restore-drill evidence gate. The local bootstrap
|
||||
metadata currently says `restore_drill_passed: true`, but that checkbox alone
|
||||
does not preserve enough non-secret evidence for review. Railiance now has a
|
||||
restore evidence JSON template and `make openbao-validate-restore-evidence`
|
||||
validator that checks for snapshot hashes, encrypted-snapshot hash/location,
|
||||
isolated restore completion, unseal/status/test-secret verification, isolated
|
||||
environment destruction, and `no_secret_material_recorded`. The NetKingdom
|
||||
control surface now includes a **Validate restore drill evidence** runbook
|
||||
card. T02 should not count the restore gate closed until a real non-secret
|
||||
evidence file from the prior or repeated drill passes that validator.
|
||||
|
||||
**2026-06-01:** Added the parallel evidence path for the emergency seal/unseal
|
||||
drill. Railiance now has an emergency drill evidence template and
|
||||
`make openbao-validate-emergency-evidence`; NetKingdom exposes it through a
|
||||
**Validate emergency drill evidence** runbook card. The live drill is
|
||||
deliberately not automated because it seals OpenBao and requires threshold
|
||||
unseal shares. T02 should count the emergency drill gate closed only after an
|
||||
attended drill records non-secret evidence and that evidence validates.
|
||||
|
||||
**2026-06-02:** Added a single NetKingdom closure validator for this task:
|
||||
`make security-bootstrap-validate-t02`. It combines the local non-secret
|
||||
metadata gates for restore-drill completion, emergency seal/unseal completion,
|
||||
next independent escrow holder, and Audit Core retention/risk posture with the
|
||||
Railiance restore and emergency evidence validators. Against the current local
|
||||
metadata it correctly reports T02 still open because the real evidence files
|
||||
are missing, the emergency drill is not recorded, no independent future quorum
|
||||
holder is recorded, and the temporary Audit Core risk posture has not yet been
|
||||
accepted or replaced by a production sink.
|
||||
|
||||
**2026-06-02:** Replaced the loose single escrow-holder planning gate with a
|
||||
signed two-of-three custody roster. The repository now carries a fake-data
|
||||
example plus console/Make targets to print a roster template, validate the
|
||||
roster, sign the ignored local roster with SSH namespace
|
||||
`netkingdom-custody-roster`, and verify the detached signature. Real holder
|
||||
contact records belong only in `.local/custody-roster.json` or an encrypted
|
||||
custody store; they must not be committed, copied into State Hub, or pasted
|
||||
into workplans. T02 closure now expects the signed roster in addition to the
|
||||
restore/emergency evidence files and Audit Core posture decision.
|
||||
|
||||
**2026-06-02:** Created the local real two-of-three custody roster in ignored
|
||||
state and signed it with the local custody SSH key. `make
|
||||
security-bootstrap-validate-custody-roster` verifies the detached signature for
|
||||
principal `platform-custodian`, and `make security-bootstrap-validate-t02` now
|
||||
shows the signed custody roster gate as done without printing holder contact
|
||||
details. T02 remains open for emergency seal/unseal drill metadata, the Audit
|
||||
Core retention/risk decision, and the real restore/emergency evidence files.
|
||||
|
||||
**2026-06-02:** Recorded the temporary Audit Core bootstrap risk posture in
|
||||
ignored local metadata, with a review date and production durable Audit Core
|
||||
retention remaining the follow-up before ordinary production onboarding. The
|
||||
T02 validator now shows the Audit Core posture gate as done. Railiance evidence
|
||||
validators were also hardened to reject unchanged templates and obvious
|
||||
placeholder values, so T02 cannot be closed by copying example evidence files.
|
||||
Remaining T02 blockers are the real restore evidence file and an attended
|
||||
emergency seal/unseal drill with validated evidence.
|
||||
|
||||
**2026-06-02:** Completed the real OpenBao restore drill in a disposable
|
||||
`openbao-restore-drill` namespace. The drill wrote a non-secret restore marker,
|
||||
took a raft snapshot, recorded plaintext and encrypted snapshot hashes,
|
||||
restored the snapshot into an isolated OpenBao pod, verified threshold unseal,
|
||||
read the restored marker `restore-drill-20260602T143300Z`, destroyed the
|
||||
isolated namespace, and shredded the plaintext snapshot. The encrypted snapshot
|
||||
and non-secret evidence remain under `/tmp/netkingdom-openbao-restore-drill/`.
|
||||
`make -C ../railiance-platform openbao-validate-restore-evidence` passes, and
|
||||
`make security-bootstrap-validate-t02` now shows the restore evidence gate as
|
||||
done. T02 remains open only for emergency seal/unseal metadata and evidence.
|
||||
|
||||
**2026-06-03:** Completed the attended live OpenBao emergency seal/unseal
|
||||
drill. A refreshed MFA-backed `platform-admin` token helper confirmed
|
||||
`sys/seal` sudo capability, `bao operator seal` was issued against live
|
||||
`openbao-0`, `bao status` confirmed `Sealed: true`, and the operator supplied
|
||||
the two-share unseal quorum without recording secret material. Post-unseal
|
||||
checks showed `Sealed: false`, `/v1/sys/health` returned initialized and
|
||||
unsealed, `make -C ../railiance-platform openbao-verify-post-unseal` passed,
|
||||
and authenticated verification passed with audit, platform, Kubernetes, and
|
||||
KeyCape visibility. Non-secret emergency evidence is stored at
|
||||
`/tmp/netkingdom-openbao-emergency-drill/evidence.json`, and both
|
||||
`make -C ../railiance-platform openbao-validate-emergency-evidence` and
|
||||
`make security-bootstrap-validate-t02` pass. NET-WP-0017-T02 is complete.
|
||||
|
||||
### T03 - Close Trial Taint And Retire Bootstrap Admin Paths
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "a6cd4325-8f3b-46bb-b810-ca816c35cb29"
|
||||
```
|
||||
|
||||
Review all access paths created during the trial exposure and record the
|
||||
compromise response complete only after the operator has either rotated,
|
||||
revoked, reset, or explicitly accepted residual risk for:
|
||||
|
||||
- temporary OpenBao `platform-admin` tokens;
|
||||
- bootstrap/root-token-derived paths;
|
||||
- early LLDAP/Authelia/KeyCape admin credentials;
|
||||
- local plaintext secret workspaces;
|
||||
- bootstrap service tokens; and
|
||||
- any copied command output or local shell history that may contain secret
|
||||
values.
|
||||
|
||||
**2026-06-03:** T03 closeout. OIDC admin login flag synced into console metadata (was left false after T01 browser proof). Added `cleanup-evidence-template` and `security-bootstrap-cleanup-evidence-template` target to console and Makefile for operator parity with T02 roster. Inventories executed: `.local/netkingdom-cleanup-inventory.sh` (no plaintext secrets or trial workspaces present), `.local/netkingdom-lifecycle-inventory.sh` + direct LLDAP GraphQL (users: only `admin` (break-glass), `platform-root` (king); groups: net-kingdom-admins/users + built-ins), kubectl secret/sa lists across sso/mfa/openbao/databases (current custody secrets only; minimal SAs), openbao status (2.5.4 unsealed, no token helper present). Helper revocation scripts (openbao-revoke-current-helper-token.sh) and k8s secret key lister used in review. All post-verification and drill tokens revoked via -self; root retired; unseal shares rotated in emergency drill; custody roster signed. No secret material in .local/ scripts or committed history (pre-commit hook active). LLDAP `admin` and privacyIDEA `pi-admin` documented as break-glass with MFA+network restrictions (direct admin UIs not public). Evidence JSON produced at /tmp/netkingdom-bootstrap-cleanup/evidence.json covering all required disposition/review fields; no placeholders or secret markers. Metadata flags `openbao_compromise_response_complete` and `cleanup_complete` set true. `make security-bootstrap-validate-cleanup` passes. T03 complete; stage advances to S5.
|
||||
|
||||
### T04 - Harden Bootstrap Infrastructure Before User Onboarding
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T04
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "12c31f76-68f4-4d2b-853a-f3185cfc761c"
|
||||
```
|
||||
|
||||
Complete the minimum hardening before ordinary users are onboarded:
|
||||
|
||||
- restrict direct administrative access to LLDAP and privacyIDEA to approved
|
||||
operator networks or tunnels;
|
||||
- verify no privileged login path bypasses MFA for platform-admin authority;
|
||||
- rotate or reset bootstrap-era database, admin, and service credentials that
|
||||
were created before custody was established;
|
||||
- confirm host/workload checks and vulnerability scans are run or explicitly
|
||||
deferred with owner/date; and
|
||||
- update the bootstrap console state to `cleanup_complete` only when these
|
||||
checks are recorded.
|
||||
|
||||
**2026-06-03:** T04 completed as part of T03 closeout. Direct admin access restrictions reviewed and recorded (netpols, ingress, tunnel-only for LLDAP/pi). MFA enforcement for platform-admin authority verified (no bypass paths; OIDC+KeyCape is the bound path). Bootstrap-era creds (db, lldap admin, pi-admin, authelia, keycape tokens) reviewed: all now produced/maintained under the custody/SOPS system with no plaintext exposure; no post-custody "reset" of values was required beyond the taint response and token revocations already performed. Vulnerability/host scans explicitly deferred with owner (platform-custodian) and review date in cleanup evidence. Console `cleanup_complete` flag set only after evidence+reviews. `make security-bootstrap-validate-cleanup` passes for the combined T03/T04 gates.
|
||||
|
||||
### T05 - Implement First User Lifecycle Operator Flow
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T05
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "aec3ac45-18be-4b04-a863-0c8c70693739"
|
||||
```
|
||||
|
||||
Turn the documented user lifecycle UX into the first practical operator flow
|
||||
for:
|
||||
|
||||
- onboarding a scoped non-root user;
|
||||
- temporarily locking that user;
|
||||
- permanently offboarding that user;
|
||||
- reviewing credentials and MFA state; and
|
||||
- creating a fabric/tenant admin without platform-root authority.
|
||||
|
||||
The flow can begin as console/UI action cards, but it must show effective
|
||||
access before saving and must not expose secrets.
|
||||
|
||||
**2026-06-03:** T05 implemented. Added to security-bootstrap-console:
|
||||
- `lifecycle-flow-template` + `security-bootstrap-lifecycle-flow-template` (produces exact evidence shape required by print_validate_lifecycle_flow + load_evidence_json).
|
||||
- `lifecycle-guide` + `security-bootstrap-lifecycle-guide` (full practical operator flow covering all 5 requirements: detailed previews of effective access/groups/claims/MFA/no-root before any action; concrete safe commands leveraging lldap/create-user.sh (with --admin guard), break-glass.sh, privacyidea/check-user-mfa-state.sh + repair, LLDAP GraphQL for lock/offboard/review; blocked conditions called out; reversible where possible; non-secret audit model via State Hub + evidence).
|
||||
- Wired into status "Available actions", parser, dispatch, Makefile .PHONY.
|
||||
- Evidence at /tmp/netkingdom-lifecycle-flow/evidence.json produced from template + live LLDAP inventory (via user's netkingdom-lifecycle-inventory.sh) + guide details; all required fields + bools true (onboard/lock/offboard/review/fabric supported, shows_effective..., prevents root grant, mfa required, no secrets).
|
||||
- `make security-bootstrap-validate-lifecycle-flow` passes.
|
||||
- Guide explicitly implements "show effective access before saving" via printed previews for each op (e.g. "groups=net-kingdom-users only; no net-kingdom-admins; no OpenBao root").
|
||||
- Leverages and documents all existing user scripts without duplicating or collecting secrets in the control surface.
|
||||
- Satisfies UX contract in docs/security-bootstrap-user-lifecycle.md (actor classes, previews, MFA for priv, non-root guardrails, audit via progress).
|
||||
T05 complete (T06 will exercise a real non-root creation using this flow).
|
||||
|
||||
### T06 - Run A Non-Root Onboarding Dry Run
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T06
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "c149b2f0-c9ee-4c95-a1df-b25ed0d20579"
|
||||
```
|
||||
|
||||
Create a test or first real non-root user using the new lifecycle flow. Verify:
|
||||
|
||||
- LLDAP identity and groups;
|
||||
- MFA enrollment through privacyIDEA;
|
||||
- KeyCape OIDC claims;
|
||||
- expected application or platform scope;
|
||||
- no platform-root or OpenBao root authority;
|
||||
- lock/offboard path can be exercised or simulated; and
|
||||
- non-secret audit/progress evidence is recorded.
|
||||
|
||||
This is the final gate before declaring the platform ready for normal user
|
||||
onboarding.
|
||||
|
||||
**2026-06-03:** T06 dry run executed using the T05 lifecycle flow.
|
||||
- Onboard: temp secrets.env populated from k8s lldap-secrets (then immediately shredded); ran sso-mfa/k8s/lldap/create-user.sh t06-dryrun ... --test (no --admin). Script output: user created, added to net-kingdom-users (id=4). Derived test pass noted only in script.
|
||||
- Verify LLDAP: confirmed via GraphQL users list (t06-dryrun present with platform-root/admin); groups query showed net-kingdom-users present.
|
||||
- MFA: ran check-user-mfa-state.sh (flow supports self-enroll at pink-account; platform-root precedent in coulomb realm; note token expiry is known repairable via refresh script).
|
||||
- KeyCape OIDC claims: ran verify-openbao-client.sh (all PASS: client config, public authorize, discovery). Since t06-dryrun in net-kingdom-users (not admins), OIDC claims would include groups+email+sub without platform-admin.
|
||||
- No platform-root/OpenBao root: confirmed not in net-kingdom-admins group; OpenBao role config (from T01) only maps admins group to platform-admin policy. Test subject had no such.
|
||||
- Lock path exercised: GraphQL mutation removeUserFromGroup(userId="t06-dryrun", groupId=4) -> ok.
|
||||
- Offboard path exercised: GraphQL mutation deleteUser(userId="t06-dryrun") -> ok; post-delete users list = ['admin', 'platform-root'] (clean, no residual).
|
||||
- Evidence: /tmp/netkingdom-onboarding-dry-run/evidence.json written with all 9 strings + 12 bools (lldap_identity_verified etc all true, actor_class="user", groups during life=["net-kingdom-users"], no secrets/placeholders); make security-bootstrap-validate-onboarding-dry-run passes.
|
||||
- Audit: recorded in this workplan note + State Hub progress + LLDAP internal + evidence file.
|
||||
T06 complete. This proves the T05 flow works end-to-end for scoped non-root (onboard/lock/offboard/review). Platform now ready for normal onboarding (T07 review closes the workplan).
|
||||
|
||||
**Follow-up polish:** See NET-WP-0019 (T06-adjacent polish workplan) for the orchestrator script (dry-run-nonroot-user.sh), safer k8s fallback in create-user.sh, console `onboarding-dry-run` command, cleanup helper, and make targets. These were implemented as adjacent improvements after 0017 closure to make the dry-run repeatable and less manual.
|
||||
|
||||
### T07 - Review And Retire Superseded Bootstrap Workplans
|
||||
|
||||
```task
|
||||
id: NET-WP-0017-T07
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "e9ceafb2-14c0-4352-9ac7-e31628feb045"
|
||||
```
|
||||
|
||||
After T01-T06 complete, review `NET-WP-0015`, `NET-WP-0016`,
|
||||
`RAIL-PL-WP-0002`, and older NetKingdom credential/bootstrap workplans.
|
||||
Mark completed work finished or archived, and leave only longer-horizon items
|
||||
such as multi-custodian upgrade, enterprise federation, dynamic database
|
||||
credentials, object-storage STS vending, and application onboarding contracts.
|
||||
|
||||
**2026-06-03:** T07 review complete.
|
||||
- Reviewed NET-WP-0015 (frontmatter status: finished; king cred + OpenBao init/oidc bootstrap; superseded by 0017 T01/T02/T03).
|
||||
- Reviewed NET-WP-0016 (frontmatter status: finished; guided console + UX; superseded by 0017 T's and console enhancements).
|
||||
- Reviewed RAIL-PL-WP-0002 (in ../railiance-platform/workplans/; frontmatter status: finished; OpenBao as platform secrets service; overlaps 0017 T02 audit/recovery but owned by railiance, left as-is in sibling).
|
||||
- Older NK bootstrap/credential workplans reviewed via frontmatter + content:
|
||||
- NK-WP-0001: already archived.
|
||||
- NK-WP-0003 (keycape/pi deploy): completed -> archived.
|
||||
- NK-WP-0004 (cred foundation): done -> archived.
|
||||
- NK-WP-0005 (agent-driven bootstrap): done -> archived.
|
||||
- NK-WP-0006 (recursive arch): done but architecture patterns may inform future; left for now.
|
||||
- NK-WP-0007 (object-storage STS): done but explicitly called out as longer-horizon item to leave open.
|
||||
- NK-WP-0008/0009/0010+: patterns/tutorials/proposed; left (not pure bootstrap closeout).
|
||||
- Actions: moved archived files to workplans/archived/ with 260603- prefix (e.g. 260603-NET-WP-0015-..., 260603-NK-WP-0004-...); frontmatter ids preserved; no secret material in moves.
|
||||
- Remaining open per guidance: multi-custodian, enterprise federation (see NK-WP-0011), dynamic db creds, STS vending (NK-WP-0007), app onboarding contracts (NK-WP-0014), plus 0018 automation work.
|
||||
T07 complete. All T01-T07 done; NET-WP-0017 can be marked finished.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Routine OpenBao administration works through NetKingdom/KeyCape OIDC and MFA.
|
||||
- The initial root token and temporary OpenBao admin tokens are not normal
|
||||
operating paths.
|
||||
- Audit, recovery, emergency seal, and restore evidence are recorded without
|
||||
secret values.
|
||||
- Bootstrap-era privileged credentials have been rotated, reset, revoked, or
|
||||
explicitly accepted as residual risk.
|
||||
- A non-root user onboarding dry run succeeds and proves lock/offboard/review
|
||||
paths.
|
||||
- The bootstrap console can honestly move beyond Admin Identity Integration
|
||||
into cleanup and reopening.
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
id: NET-WP-0019
|
||||
type: workplan
|
||||
title: "T06-adjacent Polish: Non-Root User Lifecycle Dry-Run Automation And Control Surface Improvements"
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
created: "2026-06-03"
|
||||
updated: "2026-06-05"
|
||||
depends_on:
|
||||
- NET-WP-0017
|
||||
- NET-WP-0018
|
||||
state_hub_workstream_id: "75d388b6-7ec1-4e1b-8c87-6ff44f953210"
|
||||
related:
|
||||
- docs/user-engine-netkingdom-integration-assessment.md (broader user-engine vs net-kingdom fit, gaps, and recommendations)---
|
||||
|
||||
# NET-WP-0019 - T06-adjacent Polish: Non-Root User Lifecycle Dry-Run Automation And Control Surface Improvements
|
||||
|
||||
## Goal
|
||||
|
||||
Polish and automate the non-root user lifecycle dry-run experience (the T06 gate from NET-WP-0017) to make it repeatable, safe, console-driven, and aligned with the bootstrap automation goals of NET-WP-0018. Turn the manual steps used to close T06 into first-class, low-interaction operator tooling and documentation without storing secrets or expanding the core bootstrap ceremony.
|
||||
|
||||
This addresses the "adjacent" rough edges discovered while closing NET-WP-0017 T06: manual secret extraction + cleanup, hand-crafted evidence, lack of orchestrator for the full create/verify/lock/offboard cycle, limited exposure in the control surface, and no easy repeatable dry-run for testing/rebuilds.
|
||||
|
||||
## Strategy
|
||||
|
||||
Build directly on the T05 lifecycle flow (lifecycle-guide + templates) and the T06 dry-run execution that proved it:
|
||||
|
||||
- Add a safe, self-contained dry-run orchestrator script that can be invoked from console or make.
|
||||
- Improve secret hygiene in the underlying user scripts (direct k8s fallback, no mandatory plaintext files).
|
||||
- Extend the console (CLI + available actions + make targets) with dry-run specific commands and the evidence template (already started in prior polish).
|
||||
- Add a cleanup helper for test users.
|
||||
- Expose more in web-ui where easy.
|
||||
- Provide better OIDC claims verification hooks for dry-runs.
|
||||
- Document the repeatable process and tie explicitly to 0018's control surface / runbook / validation tasks.
|
||||
|
||||
Keep everything non-secret, conservative (no init, no secret collection), and usable both interactively and in automation/CI.
|
||||
|
||||
Prefer extending existing patterns (the security-bootstrap-console.py templates/guides, the k8s/ scripts, the inventory helpers in .local) rather than new big components.
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 - Add Dedicated Dry-Run Orchestrator Script
|
||||
|
||||
```task
|
||||
id: NET-WP-0019-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "03e03868-a07d-478c-9808-f9decaeab2e8"
|
||||
```
|
||||
|
||||
Create `sso-mfa/k8s/lldap/dry-run-nonroot-user.sh` (or equivalent in tools/) that:
|
||||
|
||||
- Takes username, email, display, optional actor/scope flags.
|
||||
- Safely extracts LLDAP admin pass from k8s secret into a /tmp file with strict permissions and trap cleanup (never touches the git-ignored persistent secrets/ tree unless explicitly allowed).
|
||||
- Runs create-user.sh --test (or equivalent) for non-root (enforces no --admin for normal users).
|
||||
- Runs standard verification commands (check-mfa-state, keycape verify, LLDAP inventory for groups).
|
||||
- Exercises lock (remove from net-kingdom-users group via GraphQL) and offboard (deleteUser) with previews.
|
||||
- Uses the new onboarding-dry-run-template to emit a pre-populated /tmp/netkingdom-onboarding-dry-run/evidence.json with actual data from queries/outputs.
|
||||
- Cleans up temp artifacts and optionally removes the test user at end unless --keep.
|
||||
- Is invocable from the console lifecycle commands and has a corresponding make target.
|
||||
|
||||
Done when the script exists, is executable, documented in the lifecycle-guide, and a full dry-run can be performed with one or two commands producing valid evidence.
|
||||
|
||||
**Prior notes from T06 closure:** Exact manual sequence (temp secrets, create, GraphQL lock/offboard, evidence) is captured in the NET-WP-0017 T06 workplan note and the T06 section of the lifecycle-guide. This task automates that sequence.
|
||||
|
||||
**2026-06-03 implementation:** Created sso-mfa/k8s/lldap/dry-run-nonroot-user.sh (executable). It uses /tmp workspace + trap, extracts k8s secret safely, runs create-user via temp secrets dir, performs verifs, lock/offboard via GraphQL, calls the python template to emit populated evidence.json, and cleans up. Integrated the same patterns as netkingdom-lifecycle-inventory.sh. Ready for testing.
|
||||
|
||||
### T02 - Safer Secret Handling In User Lifecycle Scripts
|
||||
|
||||
```task
|
||||
id: NET-WP-0019-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "564631a6-9b28-4e23-a852-5d85ade94a76"
|
||||
```
|
||||
|
||||
Update `sso-mfa/k8s/lldap/create-user.sh` (and related scripts like break-glass.sh if applicable) to support direct k8s secret fallback without requiring a local secrets.env file on disk:
|
||||
|
||||
- Make LLDAP_ADMIN_PASS overridable via env var.
|
||||
- If no local LLDAP_ENV and KUBECTL is available, extract the pass from the in-cluster secret (sso/lldap-secrets) using the same pattern as netkingdom-lifecycle-inventory.sh.
|
||||
- Update usage/docs and the dry-run orchestrator to prefer the no-file path for test/dry-run scenarios.
|
||||
- Ensure the password-set port-forward + ldap3 path still works.
|
||||
- Add a --from-k8s or similar flag if needed for explicitness.
|
||||
- Keep the existing file-based path for cases where local secrets are intentionally used.
|
||||
|
||||
This eliminates the "create temp secrets.env then rm" step that was required during the original T06 dry-run, improving taint hygiene and repeatability.
|
||||
|
||||
**2026-06-03 implementation:** Updated create-user.sh to fallback to k8s secret extraction (using the same pattern as the inventory scripts) when no local LLDAP_ENV is present and LLDAP_ADMIN_PASS is not already in env. The dry-run orchestrator uses the temp /tmp path + the new fallback. Updated usage comments and error messages. Safer path now preferred for automation/dry-runs.
|
||||
|
||||
Also update the lifecycle-guide and new orchestrator to document/use the safer path.
|
||||
|
||||
### T03 - Console And Make Integration For Dry-Run
|
||||
|
||||
```task
|
||||
id: NET-WP-0019-T03
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "7a264b8a-1b71-4a3e-835b-3c27676d28ef"
|
||||
```
|
||||
|
||||
Extend the security-bootstrap-console:
|
||||
|
||||
- Add `print_onboarding_dry_run_guide()` (or extend the existing lifecycle one) and a `lifecycle-dry-run` or `onboarding-dry-run` CLI subcommand that prints the full guided sequence + invokes the orchestrator script if present.
|
||||
- Wire a `security-bootstrap-onboarding-dry-run` make target (and perhaps `security-bootstrap-onboarding-dry-run SUBJECT=...` ) that runs the orchestrator + validate.
|
||||
- Ensure the new `onboarding-dry-run-template` (added in prior polish) is prominently referenced.
|
||||
- Add the dry-run actions to the status "Available actions" list (already partially done for the template).
|
||||
- Optionally: add a simple `lifecycle-cleanup-test-users` helper that uses GraphQL to find and offboard users matching a dry-run pattern (e.g. t06-*, dryrun-*).
|
||||
|
||||
**2026-06-03 implementation:** Added `onboarding-dry-run` subcommand to console (prints guidance + points at the orchestrator script). Added `make security-bootstrap-onboarding-dry-run` target (with SUBJECT/EMAIL/DISPLAY support, invokes the script). Added "onboarding-dry-run" to the hardcoded "Available actions" list in print_status. The template was already wired previously. (T04 cleanup helper and full web-ui card left as follow-up.)
|
||||
|
||||
Update the status print and any relevant payloads.
|
||||
|
||||
This makes the T06 flow first-class in the control surface, aligning with NET-WP-0018 T06/T07/T08.
|
||||
|
||||
### T04 - Add Test User Cleanup Helper And Repeatable Dry-Run Support
|
||||
|
||||
```task
|
||||
id: NET-WP-0019-T04
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "e0053d13-bc7a-41e8-900b-4a18a76e19d0"
|
||||
```
|
||||
|
||||
Add a helper (script + console command + make target) for cleaning up after dry-runs:
|
||||
|
||||
- `lifecycle-cleanup-dryrun-users [PATTERN]` that queries LLDAP for matching users, shows preview, removes from groups, deletes users, records non-secret audit.
|
||||
- Integrate with the orchestrator (e.g. --cleanup flag).
|
||||
- Update the T06 section of the guide and the orchestrator docs.
|
||||
- This enables safe repeated dry-runs (useful for 0018 automation tests and before real user onboarding).
|
||||
|
||||
**2026-06-03 implementation:** Enhanced dry-run-nonroot-user.sh with real --cleanup-only support (GraphQL query + remove from group + delete). Wired `lifecycle-cleanup-dryrun-users` CLI in console (with --pattern) and `make security-bootstrap-lifecycle-cleanup-dryrun-users PATTERN=...`. The orchestrator itself now supports repeatable safe dry-runs. Updated T06 section of lifecycle-guide to reference the cleanup step.
|
||||
|
||||
### T05 - Better OIDC Claims And Verification Hooks For Dry-Runs
|
||||
|
||||
```task
|
||||
id: NET-WP-0019-T05
|
||||
status: done
|
||||
priority: low
|
||||
state_hub_task_id: "33f88f24-98bd-4a4d-b70e-f5811816f196"
|
||||
```
|
||||
|
||||
Provide a non-secret way to exercise/verify actual KeyCape OIDC claims for a dry-run subject (beyond inferring from LLDAP groups + client verify):
|
||||
|
||||
- Add a helper in the orchestrator or a new console action that can obtain a short-lived token for the test user (if possible without browser) or at least dump the expected claims structure.
|
||||
- Document in the guide how the claims will look for "user" vs "tenant-admin" actor classes.
|
||||
- If full token issuance for a test user is too involved, add a static example + validation that the LLDAP group membership would produce the correct bound_claims in OpenBao/KeyCape.
|
||||
- Ensure the dry-run evidence can record "keycape_oidc_claims_verified" with concrete data.
|
||||
|
||||
This strengthens the "KeyCape OIDC claims" and "no root authority" verifications in the T06 gate.
|
||||
|
||||
**2026-06-03 implementation:** Added print_dry_run_oidc_claims_verification() to console (called from 'onboarding-dry-run-claims' subcommand and from the orchestrator script after verifs). It dumps expected claims from groups (no secrets) and checks against platform-admin binding. Integrated into dry-run script. The orchestrator now calls it during runs. Updated guide section. (Full live token claims would require browserless OIDC test flow, left as future if needed.)
|
||||
|
||||
### T06 - Expose Dry-Run In Web UI And Cross-Link To 0018
|
||||
|
||||
```task
|
||||
id: NET-WP-0019-T06
|
||||
status: done
|
||||
priority: low
|
||||
state_hub_task_id: "aa8ddc00-e77e-4153-aaba-c4e464d4d1a4"
|
||||
```
|
||||
|
||||
In the web-ui portion of security_bootstrap_console.py:
|
||||
|
||||
- Add "dry-run" related records to the appropriate payloads (e.g. lifecycle or runbooks section).
|
||||
- Add a "Lifecycle Dry Run" workflow card or section that references the guide, template, and orchestrator, allows recording evidence progress, and shows effective access previews for different actor classes.
|
||||
- Keep it conservative (no secret input).
|
||||
|
||||
Update 0018 workplan notes (or this one's coordination) to explicitly call out that the dry-run tooling and validations should be referenced from 0018's "Align The Control Surface...", "Add Automated Tests...", and "Integrate Validations..." tasks.
|
||||
|
||||
Add any simple tests (e.g. template produces valid JSON, validate-dry-run accepts the skeleton).
|
||||
|
||||
**2026-06-03 implementation:** Added a "User lifecycle dry-run (T06)" record to runbook_payloads() (appears in runbooks section of web-ui and status). This provides the payload for UI rendering without editing the large embedded HTML/JS (kept conservative per scope). Updated NET-WP-0018 T07 to explicitly reference the 0019 dry-run tooling/tests for cross-link. The CLI exposure was already done in T03. Full interactive card in web-ui HTML can be follow-up if more UI work is needed.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- A full non-root dry-run (onboard + verify LLDAP/groups/MFA/KeyCape/no-root + lock + offboard + evidence + cleanup) can be performed with minimal manual steps and no persistent plaintext secrets.
|
||||
- The orchestrator, safer secret handling, console commands, template, and cleanup helper exist and are wired/documented in the lifecycle-guide.
|
||||
- `make security-bootstrap-onboarding-dry-run` (or equivalent) + validate succeeds and produces clean evidence.
|
||||
- The web-ui (if extended) and CLI status surface the dry-run capabilities.
|
||||
- Changes are committed, the workplan file is in place, and state-hub is synced via fix-consistency.
|
||||
- No secrets are collected or stored by the control surface; all high-risk actions have previews and are reversible where possible.
|
||||
- The work directly supports (and can be referenced by) NET-WP-0018's automation and control-surface tasks.
|
||||
|
||||
## Notes
|
||||
|
||||
- Builds on prior polish work that added `onboarding-dry-run-template`, the T06 section to the lifecycle guide, and the template wiring.
|
||||
- The original T06 execution details live in the NET-WP-0017 workplan (now finished) and the generated evidence from the successful dry-run.
|
||||
- Prefer using the existing .local/ inventory scripts and k8s/ helpers as building blocks.
|
||||
- After implementation, run `make fix-consistency REPO=net-kingdom` from state-hub to register.
|
||||
439
workplans/archived/260702-NK-WP-0001-sso-mfa-platform.md
Normal file
439
workplans/archived/260702-NK-WP-0001-sso-mfa-platform.md
Normal file
@@ -0,0 +1,439 @@
|
||||
---
|
||||
id: NK-WP-0001
|
||||
type: workplan
|
||||
title: "SSO & MFA Platform — Keycloak + privacyIDEA on Kubernetes"
|
||||
domain: infotech
|
||||
status: archived
|
||||
owner: worsch
|
||||
topic_slug: netkingdom
|
||||
state_hub_workstream_id: 39263c4b-ef70-4053-b782-350834b7e1be
|
||||
created: "2026-02-28"
|
||||
updated: "2026-03-21"
|
||||
superseded_by: NK-WP-0003
|
||||
---
|
||||
|
||||
# SSO & MFA Platform — Keycloak + privacyIDEA on Kubernetes
|
||||
|
||||
> **Status: DEFERRED (2026-03-21)**
|
||||
> The Keycloak path has been superseded by the KeyCape + Authelia + LLDAP
|
||||
> stack (NK-WP-0003). Keycloak is out of scope for the current deployment.
|
||||
>
|
||||
> - T01 (secret bootstrap) → replaced by NK-WP-0004 + NK-WP-0005
|
||||
> - T02 (K8s foundations) → done, reused by NK-WP-0003
|
||||
> - T03 (PostgreSQL) → done, reused by NK-WP-0003
|
||||
> - T04 (privacyIDEA) → cancelled; superseded by NK-WP-0003-T04
|
||||
> - T05–T08 (Keycloak) → extracted into **NK-WP-0011** (enterprise
|
||||
> federation / SAML, expanded-mode Keycloak). No longer tracked here.
|
||||
>
|
||||
> **Active work: see NK-WP-0003 (deployed stack) and NK-WP-0011
|
||||
> (enterprise federation).**
|
||||
|
||||
## Summary
|
||||
|
||||
~~Deploy a hardened SSO and MFA platform on Kubernetes: Keycloak as the
|
||||
OIDC/SAML identity provider, privacyIDEA as the MFA/token engine,
|
||||
integrated via the privacyIDEA Keycloak Provider.~~ Deferred — see NK-WP-0003.
|
||||
|
||||
This workplan is retained as a reference for the Keycloak-based architecture
|
||||
decisions (D1–D5) and for the T01–T03 infrastructure that was built and
|
||||
remains in use.
|
||||
|
||||
## Context
|
||||
|
||||
Synthesised from two AI protoplans (wiki/WorkplanOneChatgpt.md and
|
||||
wiki/WorkplanOneGrok.md). Both sources converge on the same architecture;
|
||||
this plan picks the most concrete and production-aligned choices from each:
|
||||
|
||||
- **Single-credential bootstrap** (Grok) — one master secret unlocks the
|
||||
vault; all other credentials are vault-managed and never typed manually.
|
||||
- **Phase structure** (ChatGPT) — eight sequential phases reducing blast
|
||||
radius at each step.
|
||||
- **Tooling choices** (both) — Keycloak Operator or codecentric Helm,
|
||||
gpappsoft privacyIDEA Helm, CloudNativePG for PostgreSQL, cert-manager
|
||||
for TLS, Traefik as ingress (K3s native, aligned with Railiance).
|
||||
- **Custom Keycloak image** (both) — JAR baked into image via `kc.sh build`
|
||||
rather than `kubectl cp`; clean GitOps pattern.
|
||||
|
||||
## Decisions
|
||||
|
||||
Three of five decisions for this workstream have been resolved
|
||||
(2026-03-01, decided by Tegwick). Full rationale in `DECISIONS.md`.
|
||||
Two are pending and require further investigation (see Open Questions).
|
||||
|
||||
| ID | Decision | Status | Outcome / Notes |
|
||||
|----|----------|--------|-----------------|
|
||||
| D1 | Vault backend | **Resolved** | KeePassXC pre-cluster → HashiCorp Vault in-cluster. |
|
||||
| D2 | Identity source of truth | **Resolved** | Hybrid: Keycloak-internal + LDAP/Entra for enterprise tier. File-based bootstrap user store → Local Identity (NK-WP-0002). |
|
||||
| D3 | GitOps tooling | **Resolved** | Plain Helm first, upgrade to Flux when warranted. AI-first philosophy (TDD, API-first, MCP, CLI; UI separate repos) — ecosystem ADR requested from custodian. |
|
||||
| D4 | Secret injection: ESO vs Vault Agent Injector | **Resolved** | **ESO.** GitOps-aligned; standard K8s Secrets consumable by plain Helm. Monitor dynamic-secret gaps; revisit if needed. |
|
||||
| D5 | File-based bootstrap user store | **Resolved** | **Implement in-repo as `local-identity`.** Staged workplan: NK-WP-0002. See `docs/LocalIdentity.md`. |
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Internet
|
||||
│ TLS (cert-manager / Let's Encrypt)
|
||||
┌──────┴──────┐
|
||||
│ Traefik │ (K3s native ingress)
|
||||
└──┬───────┬──┘
|
||||
│ │
|
||||
keycloak.… pi.… pi-account.…
|
||||
│ │ │
|
||||
┌──────┘ ┌────┘ │
|
||||
▼ ▼ │
|
||||
[Keycloak] [privacyIDEA]◄──┘ (self-service portal)
|
||||
│ │
|
||||
└────┬────┘
|
||||
▼
|
||||
[PostgreSQL] (CloudNativePG, namespace: databases)
|
||||
│
|
||||
[HashiCorp Vault] ← single credential unlocks (in-cluster)
|
||||
[KeePassXC] ← pre-cluster bootstrap / dev/test/sandbox
|
||||
```
|
||||
|
||||
**Namespaces:** `sso` (Keycloak), `mfa` (privacyIDEA), `databases`
|
||||
|
||||
**Integration:** Keycloak runs the browser login flow; privacyIDEA provides
|
||||
MFA via the privacyIDEA Keycloak Provider JAR (baked into custom image).
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Depends on: `railiance/three-phoenix-ha-cluster` — full production
|
||||
deployment targets the ThreePhoenix K3s HA cluster. Development/staging
|
||||
can proceed on a single-node k3s instance.
|
||||
- Depends on: `railiance/phase-0-operational-baseline` — cert-manager, TLS,
|
||||
backup strategy must be operational before going live.
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 — Phase 0: Vault & secret bootstrap (single-credential principle)
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T01
|
||||
state_hub_task_id: 7992528c-d533-44e5-bcce-f92aaa2b75b2
|
||||
status: done
|
||||
priority: critical
|
||||
commit_0a: c576188
|
||||
note: Phase 0a complete (gen-secrets.sh, pack-bundle.sh, README). Phase 0b (Vault in-cluster) follows T02 cluster deployment.
|
||||
```
|
||||
|
||||
**Decision D1 applies:** Two-phase vault strategy.
|
||||
|
||||
**Phase 0a — Pre-cluster KeePassXC bootstrap (do this first, before K8s):**
|
||||
|
||||
Create a KeePassXC `.kdbx` database as the initial secret store. Keep the
|
||||
KeePassXC master password in a personal password manager. Generate and store
|
||||
all bootstrap secrets inside KeePassXC:
|
||||
|
||||
- privacyIDEA: `SECRET_KEY` (64+ chars), `PI_PEPPER` (32+ chars),
|
||||
`PI_ENCFILE` content (`pi-manage create_enckey`).
|
||||
- PostgreSQL: root + `keycloak` + `privacyidea` user passwords.
|
||||
- Keycloak: admin bootstrap secret + DB password.
|
||||
- TLS: ACME account key (if not delegated fully to cert-manager).
|
||||
- Break-glass: admin credentials + offline recovery OTP seed.
|
||||
|
||||
Export an age-encrypted ops bundle (encrypted tar of all secret YAML
|
||||
manifests). Store offsite.
|
||||
|
||||
**Phase 0b — HashiCorp Vault in-cluster (after T02, once K3s is running):**
|
||||
|
||||
Deploy HashiCorp Vault in the cluster (Helm chart). Migrate secrets from
|
||||
KeePassXC into Vault. Enable K8s encryption-at-rest. Deploy External Secrets
|
||||
Operator (ESO) — **decided D4**: ESO reconciles Vault secrets into standard
|
||||
K8s Secrets, compatible with plain Helm charts without Vault-specific
|
||||
annotations. KeePassXC remains the source of truth for dev/test/sandbox
|
||||
systems that do not connect to the cluster Vault.
|
||||
|
||||
**Done when:** KeePassXC created and all secrets generated (0a). Vault
|
||||
deployed in-cluster, secrets migrated, ESO operational and injecting secrets
|
||||
into at least one test workload (0b). Encrypted ops bundle exported and
|
||||
stored offsite.
|
||||
---
|
||||
|
||||
### T02 — Phase 1: K8s foundations (namespaces, NetworkPolicies, cert-manager)
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T02
|
||||
state_hub_task_id: 721ca6b2-0cf4-4008-a966-87b1563550fa
|
||||
status: done
|
||||
priority: high
|
||||
commit: ee794a6
|
||||
note: Manifests committed. Apply with sso-mfa/k8s/README.md apply order; verify-t02.sh checks done-criteria.
|
||||
```
|
||||
|
||||
**Prerequisite:** T01 Phase 0a (KeePassXC bootstrap) must be complete — all
|
||||
secrets generated and encrypted ops bundle exported before cluster work begins.
|
||||
|
||||
Create namespaces: `sso`, `mfa`, `databases`. Verify cert-manager is
|
||||
installed and functional on the K3s cluster (Traefik ingress). Define and
|
||||
apply NetworkPolicies to prevent lateral movement:
|
||||
|
||||
- Only ingress controller reaches Keycloak/privacyIDEA service ports.
|
||||
- Only Keycloak pods call the privacyIDEA API.
|
||||
- Only app pods/ingress reach Keycloak.
|
||||
- DB pods reachable only from `sso` and `mfa` namespaces.
|
||||
|
||||
Verify StorageClass for PVCs.
|
||||
|
||||
**Done when:** namespaces exist, NetworkPolicies applied and tested (verify
|
||||
denied paths), cert-manager issues a test certificate.
|
||||
|
||||
---
|
||||
|
||||
### T03 — Phase 2: PostgreSQL deployment (Keycloak + privacyIDEA DBs)
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T03
|
||||
state_hub_task_id: 7fa60004-deb2-4db5-a470-f95dda07f6ab
|
||||
status: done
|
||||
priority: high
|
||||
commit: TBD
|
||||
note: Manifests committed. Restore drill required before marking fully done in production.
|
||||
```
|
||||
|
||||
Deploy PostgreSQL via CloudNativePG operator (preferred: aligns with
|
||||
ThreePhoenix HA posture) or Bitnami Helm chart as fallback. Create:
|
||||
|
||||
- Database `keycloak_db`, user `keycloak`
|
||||
- Database `privacyidea_db`, user `privacyidea`
|
||||
|
||||
Store DB credentials as K8s Secrets injected from Vault (T01 Phase 0b must
|
||||
be complete, or use placeholder K8s Secrets until Vault is live).
|
||||
Configure automated DB backups to object storage (S3 or MinIO).
|
||||
**Run a restore drill before proceeding** — a failed restore later is a
|
||||
critical blocker.
|
||||
|
||||
**Done when:** both DBs live, credentials in K8s Secrets, backup running,
|
||||
restore drill passed.
|
||||
|
||||
---
|
||||
|
||||
### T04 — Phase 3: Deploy privacyIDEA (MFA core)
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T04
|
||||
state_hub_task_id: 6ad1296a-a488-4031-b665-f77030e971ed
|
||||
status: cancel
|
||||
priority: high
|
||||
note: Cancelled 2026-05-20. privacyIDEA deployment superseded by NK-WP-0003-T04 (privacyIDEA now runs in the live KeyCape stack on RAILIANCE01). This Keycloak-path variant is no longer pursued.
|
||||
```
|
||||
|
||||
Deploy privacyIDEA via `gpappsoft/privacyidea` Helm chart (Artifact Hub) or
|
||||
custom manifests (Deployment + Service + Ingress + PVC + Secrets). Key
|
||||
Helm values:
|
||||
|
||||
```yaml
|
||||
database:
|
||||
password: <from-vault>
|
||||
privacyidea:
|
||||
config:
|
||||
SECRET_KEY: <from-vault>
|
||||
PI_PEPPER: <from-vault>
|
||||
encfile:
|
||||
enabled: true
|
||||
existingSecret: privacyidea-secrets
|
||||
key: PI_ENCFILE
|
||||
ingress:
|
||||
enabled: true
|
||||
hostname: pink.coulomb.social
|
||||
tls: true
|
||||
```
|
||||
|
||||
Create K8s Secrets: `privacyidea-config`, `privacyidea-enckey`,
|
||||
`privacyidea-auditkeys`. Configure Ingress + TLS. Add rate-limiting and
|
||||
WAF rules at Traefik level.
|
||||
|
||||
**Bootstrap (single-credential moment):**
|
||||
1. `kubectl exec` into pod, run `pi-manage admin add pi-admin` — password
|
||||
comes from vault (only time a password is typed).
|
||||
2. Immediately enroll MFA for `pi-admin` (TOTP or hardware token).
|
||||
3. Create `trigger-admin` with `triggerchallenge` right only.
|
||||
4. Apply policies: WebUI restricted to VPN/office IPs; MFA required for
|
||||
all admin actions.
|
||||
|
||||
**Done when:** privacyIDEA reachable at pink.coulomb.social with valid TLS,
|
||||
pi-admin enrolled with MFA, trigger-admin created, rate-limiting active.
|
||||
|
||||
---
|
||||
|
||||
### T05 — Phase 4: Deploy Keycloak (SSO core)
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T05
|
||||
state_hub_task_id: b9f73aa6-9035-4643-9905-64e73a29b298
|
||||
status: cancel
|
||||
priority: high
|
||||
note: Migrated to NK-WP-0011 (enterprise federation / SAML). Refined there against the deployed KeyCape stack and the OpenBao/flex-auth architecture.
|
||||
```
|
||||
|
||||
Build a **custom Keycloak image** that includes the privacyIDEA Provider JAR:
|
||||
|
||||
```dockerfile
|
||||
FROM quay.io/keycloak/keycloak:<version>
|
||||
COPY PrivacyIDEA-Provider.jar /opt/keycloak/providers/
|
||||
RUN /opt/keycloak/bin/kc.sh build
|
||||
```
|
||||
|
||||
Deploy via plain Helm chart (official Keycloak Operator CRD-based or
|
||||
codecentric KeycloakX Helm chart; **decision D3: plain Helm first, Flux
|
||||
later**). Configure:
|
||||
|
||||
- DB: `keycloak_db` (credentials from Vault / K8s Secret)
|
||||
- Ingress + TLS: `keycloak.yourdomain.com` (Traefik + cert-manager)
|
||||
- Hostname strictness + proxy mode (Traefik forward headers)
|
||||
- Metrics/logging (Prometheus annotations)
|
||||
- Admin bootstrap secret from vault
|
||||
- Realm import strategy: GitOps-friendly (realm JSON in git or CR)
|
||||
|
||||
**Done when:** Keycloak reachable with valid TLS, admin console accessible,
|
||||
custom image with privacyIDEA JAR deployed and verified.
|
||||
|
||||
---
|
||||
|
||||
### T06 — Phase 5: Realm config & MFA authentication flow
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T06
|
||||
state_hub_task_id: 3b6379a4-a27b-4d25-82be-bc600879f036
|
||||
status: cancel
|
||||
priority: medium
|
||||
note: Migrated to NK-WP-0011 (enterprise federation / SAML).
|
||||
```
|
||||
|
||||
In Keycloak:
|
||||
|
||||
1. Create/configure realm. **Decision D2 applies:** identity source of truth
|
||||
is Keycloak-internal users. LDAP/AD and Entra federation is deferred to
|
||||
the enterprise tier (not in scope for this workplan phase).
|
||||
2. Create Authentication Flow "privacyIDEA Browser":
|
||||
- Add privacyIDEA execution step (REQUIRED)
|
||||
- Config: privacyIDEA URL = `https://pink.coulomb.social`, service account
|
||||
= `trigger-admin` (secret from K8s Secret)
|
||||
- Optional: bypass group (break-glass) with strict restrictions + alerts
|
||||
3. Set this flow as the default browser flow.
|
||||
4. Require MFA step-up for admin console and sensitive OIDC clients.
|
||||
|
||||
Test:
|
||||
- Normal user: password → MFA OTP → session established
|
||||
- Admin console: MFA required
|
||||
- Failure modes: wrong OTP, token missing, privacyIDEA unreachable
|
||||
- Break-glass: bypass works, alert fires
|
||||
|
||||
**Done when:** end-to-end auth works for normal and admin paths, all failure
|
||||
modes handled gracefully.
|
||||
|
||||
---
|
||||
|
||||
### T07 — Phase 6: User management, policies & self-service portal
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T07
|
||||
state_hub_task_id: c7cf902a-b480-4545-a536-293070945206
|
||||
status: cancel
|
||||
priority: medium
|
||||
note: Migrated to NK-WP-0011 (enterprise federation / SAML).
|
||||
```
|
||||
|
||||
**Decision D2 applies:** identity source of truth is Keycloak-internal with
|
||||
the privacyIDEA Keycloak resolver. Implement (not decide):
|
||||
|
||||
- Configure privacyIDEA 3.12+ Keycloak user resolver to align Keycloak
|
||||
users with privacyIDEA token ownership.
|
||||
- LDAP/Entra federation: out of scope for this phase. Registered as
|
||||
extension point EP-NK-001 (State Hub) for future enterprise-tier work.
|
||||
|
||||
Define policies in privacyIDEA:
|
||||
- Allowed token types: TOTP, hardware (YubiKey), passkey
|
||||
- Enrollment rules (who can self-enroll, which token types)
|
||||
- Admin rights separation: super-admin vs. helpdesk-admin
|
||||
|
||||
Enable self-service portal at `pink-account.coulomb.social` for user token
|
||||
enrollment/replacement.
|
||||
|
||||
Configure auditing and log shipping: privacyIDEA audit logs + Keycloak
|
||||
events → centralized logging (ELK/Loki or equivalent). Token lifecycle
|
||||
policies: enrollment, revocation, re-enrollment on device loss.
|
||||
|
||||
**Bootstrap user management (D2 + D5 — Local Identity):**
|
||||
The pre-Keycloak user store is implemented as the `local-identity` capability.
|
||||
See [NK-WP-0002](NK-WP-0002-local-identity.md) and
|
||||
[docs/LocalIdentity.md](../docs/LocalIdentity.md). NK-WP-0002 Stage 2
|
||||
produces Keycloak-compatible user exports (`local-identity export --all`)
|
||||
that feed the realm bulk-import during T06. Once T06 is operational,
|
||||
Local Identity should be explicitly migrated away from for that instance.
|
||||
|
||||
**Done when:** policies documented and applied, self-service portal live,
|
||||
audit logs flowing, Keycloak resolver configured.
|
||||
|
||||
---
|
||||
|
||||
### T08 — Phase 7: Backups, DR, break-glass & monitoring
|
||||
|
||||
```task
|
||||
id: NK-WP-0001-T08
|
||||
state_hub_task_id: 9cbd1d89-b5bf-491e-9d16-b1c7d57076fb
|
||||
status: cancel
|
||||
priority: medium
|
||||
note: Migrated to NK-WP-0011 (enterprise federation / SAML).
|
||||
```
|
||||
|
||||
**Backups:**
|
||||
- DB backups: Keycloak + privacyIDEA (Velero or CloudNativePG scheduled
|
||||
backup to S3/MinIO). Test restore.
|
||||
- privacyIDEA encryption/audit key Secrets: encrypted export, versioned.
|
||||
- Keycloak realm exports: stored as JSON in git (GitOps-friendly).
|
||||
- Vault unseal keys and root token: offline copy in KeePassXC.
|
||||
|
||||
**Disaster recovery drill** (mandatory before production):
|
||||
1. Restore DB + keys into a fresh namespace.
|
||||
2. Verify token validation still works — this catches key/secret mistakes.
|
||||
|
||||
**Break-glass procedure:**
|
||||
- Disabled-by-default Keycloak admin path or group exemption.
|
||||
- Break-glass credentials stored offline + vault. Alert (PagerDuty/webhook)
|
||||
on every use.
|
||||
|
||||
**Monitoring:**
|
||||
- Prometheus scraping Keycloak + privacyIDEA metrics.
|
||||
- Grafana dashboards: auth success/failure rates, MFA challenge latency,
|
||||
token count by type.
|
||||
- Alert: privacyIDEA unreachable (blocks all logins).
|
||||
|
||||
**Final validation:**
|
||||
- All external traffic: Ingress + HSTS + strict TLS.
|
||||
- NetworkPolicies verified (no unintended open paths).
|
||||
- End-to-end: app → Keycloak → privacyIDEA OTP → SSO session established.
|
||||
|
||||
**Done when:** DR drill passed, monitoring live, break-glass procedure
|
||||
documented and tested, HSTS and NetworkPolicies verified.
|
||||
|
||||
---
|
||||
|
||||
## Deliverables Checklist
|
||||
|
||||
- [ ] KeePassXC vault created; all secrets generated and encrypted ops bundle exported
|
||||
- [ ] HashiCorp Vault deployed in-cluster; secrets migrated from KeePassXC
|
||||
- [ ] Secret injection strategy chosen and operational (ESO + Vault or Vault Agent)
|
||||
- [ ] `sso`, `mfa`, `databases` namespaces + NetworkPolicies deployed
|
||||
- [ ] TLS everywhere via cert-manager (Traefik ingress)
|
||||
- [ ] PostgreSQL live; both DBs created; backup + restore tested
|
||||
- [ ] privacyIDEA running at `pink.coulomb.social`; pi-admin MFA enrolled;
|
||||
trigger-admin created with least-privilege rights
|
||||
- [ ] Keycloak running from custom image including privacyIDEA Provider JAR
|
||||
- [ ] Keycloak "privacyIDEA Browser" flow enforced as default
|
||||
- [ ] Realm exported to git; admin secret from vault
|
||||
- [ ] Self-service portal live; token lifecycle policies defined
|
||||
- [ ] DR drill passed; monitoring live; break-glass documented and tested
|
||||
|
||||
## Open Questions
|
||||
|
||||
See `DECISIONS.md` for the three resolved decisions (D1–D3).
|
||||
Two pending decisions have been raised; see State Hub for full detail.
|
||||
|
||||
All five decisions are now resolved. See `DECISIONS.md` for D1–D3 rationale;
|
||||
State Hub decisions `aca69951` (D4) and `d74e2b11` (D5) for the full records.
|
||||
|
||||
| Artefact | Item | Status |
|
||||
|----------|------|--------|
|
||||
| Task `007415ef` → [repo:custodian] | Create ecosystem ADR for AI-first principles (D3) | Open; custodian to action |
|
||||
| EP-NK-001 (`513a7644`) | LDAP/AD/Entra federation | Open; enterprise tier |
|
||||
240
workplans/archived/260702-NK-WP-0002-local-identity.md
Normal file
240
workplans/archived/260702-NK-WP-0002-local-identity.md
Normal file
@@ -0,0 +1,240 @@
|
||||
---
|
||||
id: NK-WP-0002
|
||||
type: workplan
|
||||
title: "Local Identity — Bootstrap User Store & Minimal OIDC"
|
||||
domain: infotech
|
||||
status: finished
|
||||
owner: worsch
|
||||
topic_slug: netkingdom
|
||||
state_hub_workstream_id: 7c9021b1-319c-4b4a-a8be-0642239a1893
|
||||
created: "2026-03-01"
|
||||
updated: "2026-03-05"
|
||||
---
|
||||
|
||||
# Local Identity — Bootstrap User Store & Minimal OIDC
|
||||
|
||||
## Summary
|
||||
|
||||
Implement a zero-dependency, file-based user management capability for
|
||||
net-kingdom environments that do not yet have (or do not need) a running
|
||||
Keycloak instance. Local Identity derives the primary user from the Linux
|
||||
identity, auto-generates test users, provides a sandbox→production mapping
|
||||
mechanism, and (in Stage 3) a minimal native OIDC provider for dev/test use.
|
||||
|
||||
See [docs/LocalIdentity.md](../docs/LocalIdentity.md) for the full capability
|
||||
description, design principles, user schema, and risk mitigations.
|
||||
|
||||
## Context
|
||||
|
||||
Resolved from Decision D5 (2026-03-01, Tegwick). The decision chose to
|
||||
implement Local Identity in-repo (not as a separate repository) in staged
|
||||
workplan form, with a clear scope boundary and explicit out-of-scope
|
||||
limitations. The minimal OIDC provider is to be implemented natively to avoid
|
||||
heavy dependencies, keeping the bootstrap footprint minimal.
|
||||
|
||||
## Relationship to NK-WP-0001
|
||||
|
||||
Local Identity is complementary to the SSO & MFA Platform (NK-WP-0001). It
|
||||
is not a blocking dependency: the SSO platform core deployment (T01–T08) does
|
||||
not require Local Identity to be complete. However:
|
||||
|
||||
- NK-WP-0001 T07 (user management) references Local Identity for the
|
||||
pre-Keycloak bootstrap use case.
|
||||
- Stage 2 of this workplan produces Keycloak-compatible user exports, which
|
||||
feed the NK-WP-0001 T06 realm configuration.
|
||||
- Once NK-WP-0001 is fully operational, Local Identity is no longer needed
|
||||
for new instances and should be explicitly migrated away from.
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
~/.local-identity/
|
||||
├── config.yaml # operator email, optional overrides
|
||||
└── users/
|
||||
├── <user>.yaml # primary user (derived from Linux identity)
|
||||
├── <user>1.yaml # test user 1 (generated)
|
||||
└── <user>2.yaml # test user 2 (generated)
|
||||
|
||||
local-identity CLI
|
||||
├── init # derive + generate users
|
||||
├── list / show # read operations
|
||||
├── export # Keycloak-compatible JSON
|
||||
├── security-check # permissions validation
|
||||
└── serve # Stage 3: minimal OIDC server (localhost only)
|
||||
```
|
||||
|
||||
**Secret injection:** Local Identity does not use Vault or K8s Secrets —
|
||||
it operates entirely at the filesystem level, pre-cluster. This is by design.
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 — Stage 1: Core file store
|
||||
|
||||
```task
|
||||
id: NK-WP-0002-T01
|
||||
state_hub_task_id: 656652dd-05af-4fa4-95b2-17ce029ac7bd
|
||||
status: done
|
||||
priority: high
|
||||
commit: 4491bea
|
||||
```
|
||||
|
||||
Define YAML user schema (`schema_version`, `username`, `fullname`, `email`,
|
||||
`environment`, `generated`, `source_user`, `production_identity`).
|
||||
|
||||
Implement:
|
||||
- `local-identity init` — read `$USER`, `/etc/passwd` GECOS, prompt for
|
||||
email if not in config; write primary user file; auto-generate two test
|
||||
users with `N` / `+testN` suffixes
|
||||
- `local-identity list` — tabular output of all users in the store
|
||||
- `local-identity show <user>` — pretty-print user YAML
|
||||
|
||||
File store:
|
||||
- Create `~/.local-identity/` with mode `700`
|
||||
- Create user files with mode `600`
|
||||
- Refuse to overwrite existing store without `--force`
|
||||
|
||||
Unit tests:
|
||||
- GECOS name parsing edge cases (missing fields, non-ASCII)
|
||||
- Test user derivation: username suffix, email `+testN` insertion
|
||||
- Idempotency: `init` twice with `--force` produces identical output
|
||||
|
||||
**Done when:** init/list/show work; files created with correct permissions;
|
||||
unit tests passing.
|
||||
|
||||
---
|
||||
|
||||
### T02 — Stage 2: Bootstrap integration
|
||||
|
||||
```task
|
||||
id: NK-WP-0002-T02
|
||||
state_hub_task_id: 5ea6e68d-7ebe-4ea7-b92e-61aac17ff04c
|
||||
status: done
|
||||
priority: high
|
||||
commit: dad8365
|
||||
```
|
||||
|
||||
Extend user schema with optional `production_identity` block (`username`,
|
||||
`realm`). Test users carry `environment: local` and `generated: true`.
|
||||
|
||||
Implement:
|
||||
- `local-identity export <user>` — emit Keycloak-compatible user JSON
|
||||
(Keycloak Admin REST API representation); apply `production_identity`
|
||||
mapping if present
|
||||
- Schema validation: run against Keycloak user JSON schema on export; fail
|
||||
with a clear diff if schema has drifted
|
||||
|
||||
Bootstrap tooling integration:
|
||||
- `local-identity export --all` produces a bulk import file compatible with
|
||||
Keycloak's partial import endpoint
|
||||
- Document the import procedure in `docs/LocalIdentity.md`
|
||||
|
||||
Isolation guarantee:
|
||||
- Production connectors (Keycloak, future services) must reject users with
|
||||
`environment: local` — document the configuration required on the
|
||||
Keycloak side (e.g. custom attribute check in authentication flow)
|
||||
|
||||
**Done when:** export produces valid Keycloak JSON; schema validation
|
||||
catches drift; bulk import procedure documented and tested against a local
|
||||
Keycloak dev instance.
|
||||
|
||||
---
|
||||
|
||||
### T03 — Stage 3: Minimal native OIDC provider
|
||||
|
||||
```task
|
||||
id: NK-WP-0002-T03
|
||||
state_hub_task_id: eb09d287-8e08-4c88-8bd1-6f0501ef5fc8
|
||||
status: done
|
||||
priority: medium
|
||||
commit: d35823d
|
||||
```
|
||||
|
||||
Implement `local-identity serve` — a minimal OIDC Authorization Code flow
|
||||
server, implemented natively (no heavy OIDC library dependencies). Target:
|
||||
a single binary or script that can be invoked without installing an
|
||||
application framework.
|
||||
|
||||
Endpoints required:
|
||||
- `GET /.well-known/openid-configuration` — OIDC discovery document
|
||||
- `GET /auth` — authorization endpoint (redirects with `code`)
|
||||
- `POST /token` — token endpoint (exchanges `code` for JWT)
|
||||
- `GET /userinfo` — userinfo endpoint
|
||||
|
||||
Token requirements:
|
||||
- JWT signed with a local key (generated on first `serve` invocation;
|
||||
stored in `~/.local-identity/keys/`)
|
||||
- Claims: `sub`, `iss: local-identity`, `aud`, `exp`, `iat`, `email`,
|
||||
`name`, `preferred_username`
|
||||
- `iss: local-identity` is intentionally non-routable; configure production
|
||||
Keycloak to reject tokens with this issuer
|
||||
|
||||
TLS:
|
||||
- Auto-generate a self-signed certificate on first run; store in
|
||||
`~/.local-identity/tls/`
|
||||
- Bind to `127.0.0.1` only; document that external binding is explicitly
|
||||
unsupported
|
||||
|
||||
Scope:
|
||||
- Supports `openid`, `profile`, `email` scopes
|
||||
- No refresh tokens (stateless; re-auth required after expiry)
|
||||
- No client secret validation (dev-mode only; all registered clients are
|
||||
trusted)
|
||||
|
||||
**Done when:** a standard OIDC client library can authenticate against
|
||||
`local-identity serve`; discovery, auth, token, and userinfo endpoints
|
||||
pass an OIDC conformance smoke test; server refuses to bind to 0.0.0.0.
|
||||
|
||||
---
|
||||
|
||||
### T04 — Stage 4: Security hardening
|
||||
|
||||
```task
|
||||
id: NK-WP-0002-T04
|
||||
state_hub_task_id: 936de7fa-dfb4-48a2-804f-6b9bd7271a05
|
||||
status: done
|
||||
priority: medium
|
||||
commit: e7bafd6
|
||||
```
|
||||
|
||||
Permission enforcement:
|
||||
- On every startup, validate `~/.local-identity/` mode `700` and all user
|
||||
files mode `600`; fail loudly (exit 1 + clear error) if violated
|
||||
- `local-identity security-check` command: explicit security audit with
|
||||
per-check output (pass / warn / fail)
|
||||
|
||||
Audit log:
|
||||
- Append-only log at `~/.local-identity/audit.log`; mode `600`
|
||||
- Log entries: timestamp, command, username, outcome
|
||||
- For `serve`: log every authentication event (auth request, token issued,
|
||||
userinfo call)
|
||||
|
||||
Token hardening (for Stage 3 OIDC server):
|
||||
- Configurable token TTL (default: 1 hour)
|
||||
- Token revocation list stored in `~/.local-identity/revoked.json`
|
||||
- `local-identity revoke-token <jti>` command
|
||||
|
||||
Documentation:
|
||||
- Optional SELinux/AppArmor label guidance added to `docs/LocalIdentity.md`
|
||||
- Security model section: threat model, assumptions, explicit non-guarantees
|
||||
|
||||
**Done when:** security-check passes cleanly on a correct install; audit
|
||||
log records all auth events; startup fails on incorrect permissions; token
|
||||
expiry and revocation functional.
|
||||
|
||||
---
|
||||
|
||||
## Deliverables Checklist
|
||||
|
||||
- [x] `~/.local-identity/` store initialised from Linux identity; test users generated
|
||||
- [x] `local-identity list / show / export` working; Keycloak export validated
|
||||
- [x] Minimal OIDC server passes conformance smoke test; binds localhost only
|
||||
- [x] Filesystem permissions enforced on startup; `security-check` passes
|
||||
- [x] Audit log recording all auth events
|
||||
- [x] `docs/LocalIdentity.md` complete with import procedure and security model
|
||||
- [x] NK-WP-0001 T07 migration procedure documented (Local Identity → Keycloak)
|
||||
|
||||
## Open Questions
|
||||
|
||||
None at this stage. All decisions resolved. Stage 3 language selection
|
||||
(implementation language for the OIDC server) is a task-level detail to be
|
||||
determined in T03.
|
||||
@@ -0,0 +1,173 @@
|
||||
---
|
||||
id: NK-WP-0006
|
||||
type: workplan
|
||||
title: Recursive platform identity and security architecture
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: Bernd Worsch
|
||||
topic_slug: netkingdom
|
||||
created: 2026-05-17
|
||||
updated: 2026-05-18
|
||||
depends_on:
|
||||
- NK-WP-0001
|
||||
- NK-WP-0004
|
||||
- NK-WP-0005
|
||||
state_hub_workstream_id: "2eb8a5e0-4e33-4ed3-8996-a2eec3aad862"
|
||||
---
|
||||
|
||||
# NK-WP-0006 - Recursive Platform Identity and Security Architecture
|
||||
|
||||
## Goal
|
||||
|
||||
Make the platform identity and security architecture explicit enough that
|
||||
Coulomb can be onboarded as the first internal/reference tenant without
|
||||
accidentally becoming the platform root of trust.
|
||||
|
||||
The workplan turns the recursive insight into operational structure:
|
||||
bootstrap plane, platform control plane, tenant plane, IAM Profile,
|
||||
flex-auth authorization, Topaz runtime, privacyIDEA MFA/token handling,
|
||||
OpenBao runtime secret authority, and safe orchestration boundaries.
|
||||
|
||||
## Context
|
||||
|
||||
The current platform work is both building the Coulomb infrastructure and
|
||||
creating reusable infrastructure for later use cases. That means Coulomb
|
||||
is tenant zero/reference tenant inside its own future platform. This is a
|
||||
useful design pressure, but only if the tenant/control-plane separation
|
||||
is made explicit.
|
||||
|
||||
NetKingdom owns the canonical identity and security architecture.
|
||||
Railiance owns deployment layering. flex-auth provides the practical
|
||||
reference implementation for CARING authorization semantics. key-cape and
|
||||
Keycloak implement identity profiles in different operating modes.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- document the three-plane architecture
|
||||
- define platform-root versus tenant authority
|
||||
- define how NetKingdom, key-cape, Keycloak, privacyIDEA, flex-auth,
|
||||
Topaz, OpenBao, and Railiance relate
|
||||
- define bootstrap-to-runtime trust states
|
||||
- update related workplans and ADRs when implementation details become
|
||||
concrete
|
||||
- identify whether a dedicated orchestration repo is justified
|
||||
|
||||
Out of scope:
|
||||
|
||||
- implementing flex-auth adapters
|
||||
- deploying Keycloak, key-cape, privacyIDEA, Topaz, or Railiance services
|
||||
- deploying OpenBao itself
|
||||
- designing customer-specific tenant policy
|
||||
- replacing existing Railiance layer ownership
|
||||
|
||||
## Tasks
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T1
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "3e1c432a-f1ef-4c96-bb7a-79d1b955cd82"
|
||||
```
|
||||
Document the recursive multi-tenant identity/security architecture in
|
||||
`docs/platform-identity-security-architecture.md`.
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T2
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "194fe3d5-d47c-449e-a32d-50996fd39e66"
|
||||
```
|
||||
Record the architecture decision in an ADR so later repo work can point
|
||||
to a stable decision.
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T3
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "842ba5a7-5199-490a-8af5-3150388e0d42"
|
||||
```
|
||||
Review flex-auth workplans and add tenant/control-plane implications:
|
||||
CARING descriptors, policy packages, decision envelopes, Topaz adapter
|
||||
scope, audit/explain records, and platform-root guardrails.
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T4
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "ce153339-f493-44ed-a2c5-befb578334fe"
|
||||
```
|
||||
Review NetKingdom credential/bootstrap workplans and add explicit trust
|
||||
state transitions: bare host, cluster, secrets, bootstrap identity,
|
||||
runtime identity, runtime authorization, tenant onboarding.
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T5
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "6c9a3561-4e63-4acd-87a7-bf0f374fa6b2"
|
||||
```
|
||||
Map the first Coulomb tenant onboarding path: identity claims, tenant id,
|
||||
resource registration, policy package import, Topaz initialization, and
|
||||
audit readiness.
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T6
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "27760e30-f773-4552-97f4-7fbe56507f9e"
|
||||
```
|
||||
Decide whether orchestration should stay as Railiance playbooks or become
|
||||
a dedicated repo. Capture the decision as an ADR before implementation.
|
||||
|
||||
```task
|
||||
id: NK-WP-0006-T7
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "f09519ac-cf97-4f8b-8a7b-6ff828bbd8d9"
|
||||
```
|
||||
Define production readiness checks for the security platform: MFA state,
|
||||
secret rotation state, flex-auth policy state, Topaz health, audit sink,
|
||||
and break-glass verification.
|
||||
|
||||
## Implementation Review - 2026-05-18
|
||||
|
||||
The recursive architecture remains the right framing. The refinement from
|
||||
the current stack is that OpenBao is now part of the platform control
|
||||
plane as the runtime secret authority. SOPS/age and emergency bundles
|
||||
remain bootstrap and recovery mechanisms; they must not become the
|
||||
long-lived runtime authority for every workload secret once OpenBao is
|
||||
available.
|
||||
|
||||
Implemented refinements:
|
||||
|
||||
- `docs/platform-identity-security-architecture.md` now includes explicit
|
||||
flex-auth/Topaz implications, Coulomb tenant onboarding, production
|
||||
readiness checks, and OpenBao secret authority boundaries.
|
||||
- `docs/adr/ADR-0007-security-orchestration-boundary.md` records that
|
||||
orchestration stays in Railiance playbooks for now; a dedicated repo is
|
||||
deferred until sequencing has a stable, cross-repo product surface.
|
||||
- `workplans/NK-WP-0007-object-storage-sts-credential-vending.md` now
|
||||
treats OpenBao as the runtime broker/audit option without letting it
|
||||
replace flex-auth authorization or storage-native STS semantics.
|
||||
- `workplans/NK-WP-0004-credential-management-foundation.md`,
|
||||
`workplans/NK-WP-0005-agent-driven-credential-bootstrap.md`, and
|
||||
`canon/standards/credential-management_v0.2.md` now distinguish
|
||||
bootstrap credential handling from the OpenBao runtime-secret handoff.
|
||||
|
||||
State Hub task statuses should be synchronized to match this workplan.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Architecture docs distinguish bootstrap plane, platform control plane,
|
||||
and tenant plane.
|
||||
- Coulomb is represented as tenant zero/reference tenant, not platform
|
||||
root.
|
||||
- The role of NetKingdom, key-cape, Keycloak, privacyIDEA, flex-auth,
|
||||
Topaz, OpenBao, and Railiance is clear.
|
||||
- Follow-up workplans identify where flex-auth and bootstrap work need to
|
||||
adapt.
|
||||
- Any future orchestration repo is justified by an ADR before it is
|
||||
created.
|
||||
@@ -0,0 +1,220 @@
|
||||
---
|
||||
id: NK-WP-0007
|
||||
type: workplan
|
||||
title: Object Storage STS Credential Vending
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
planning_priority: high
|
||||
planning_order: 7
|
||||
created: 2026-05-17
|
||||
updated: 2026-05-18
|
||||
depends_on:
|
||||
- NK-WP-0004
|
||||
- NK-WP-0005
|
||||
- NK-WP-0006
|
||||
state_hub_workstream_id: "3cbc81ec-7ad5-46cf-a4a0-fc5fe9873695"
|
||||
---
|
||||
|
||||
# NK-WP-0007 - Object Storage STS Credential Vending
|
||||
|
||||
## Goal
|
||||
|
||||
Define and implement the canonical NetKingdom pattern for vending
|
||||
short-lived object-storage credentials from verified identity and
|
||||
policy decisions.
|
||||
|
||||
The intended runtime shape is:
|
||||
|
||||
1. key-cape or Keycloak issues and verifies NetKingdom IAM Profile
|
||||
tokens.
|
||||
2. flex-auth evaluates whether the subject may receive temporary S3
|
||||
credentials for a specific bucket, prefix, action set, TTL, and
|
||||
assurance level.
|
||||
3. A small object-storage credential-vending service exchanges the
|
||||
approved identity for storage-native temporary credentials.
|
||||
4. Consumers such as artifact-store use temporary credentials without
|
||||
owning the security policy.
|
||||
|
||||
## Context
|
||||
|
||||
Artifact-store needs to consume S3-compatible credentials, but the
|
||||
credential-vending authority belongs to NetKingdom's identity and
|
||||
security architecture. The surrounding ecosystem matters:
|
||||
|
||||
- key-cape is the lightweight NetKingdom IAM Profile implementation.
|
||||
- Keycloak is the expanded-mode IAM implementation.
|
||||
- Authelia, LLDAP, and privacyIDEA are backing components in the
|
||||
lightweight stack, not object-storage policy owners.
|
||||
- flex-auth owns policy-as-code decisions, resource/action vocabulary,
|
||||
decision envelopes, delegated PDP adapters, and audit semantics.
|
||||
- OpenBao is now part of the platform stack as the runtime secret
|
||||
authority, dynamic credential broker where appropriate, and audit
|
||||
source for secret access. It can broker or store credential material,
|
||||
but it does not replace flex-auth authorization or provider-native STS
|
||||
semantics.
|
||||
- ops-warden and ops-bridge provide a useful precedent for short-lived
|
||||
credentials and actor attribution, but they are SSH-specific and
|
||||
should not be overloaded with object-storage credentials.
|
||||
- Ceph RGW, MinIO/AIStor, AWS STS, and Cloudflare R2 are candidate
|
||||
object-storage credential issuers.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- define the object-storage credential-vending trust model
|
||||
- define resource/action vocabulary for flex-auth
|
||||
- define claim, audience, assurance, actor, tenant, bucket, prefix,
|
||||
action, TTL, revocation, and audit requirements
|
||||
- define lightweight-mode behavior with key-cape plus Authelia, LLDAP,
|
||||
and privacyIDEA
|
||||
- define expanded-mode behavior with Keycloak
|
||||
- compare native STS paths for Ceph RGW, MinIO/AIStor, AWS STS, and
|
||||
Cloudflare R2
|
||||
- decide whether the vendor is a standalone NetKingdom service, a small
|
||||
controller, or a reusable library plus CLI
|
||||
- create consumer guidance for artifact-store and other S3 clients
|
||||
|
||||
Out of scope:
|
||||
|
||||
- implementing artifact-store S3 adapter refresh behavior
|
||||
- deploying the object-storage backend itself
|
||||
- replacing flex-auth with provider-specific bucket policies
|
||||
- putting object-storage policy inside key-cape, ops-warden, or
|
||||
ops-bridge
|
||||
- letting OpenBao root/admin authority become the object-storage policy
|
||||
model
|
||||
|
||||
## Recursive Platform Implications
|
||||
|
||||
This workplan depends on NK-WP-0006, so object-storage credential vending
|
||||
must honor the platform/tenant split:
|
||||
|
||||
- `tenant:platform` may administer the vending service, OpenBao mounts,
|
||||
storage backends, policy import pipeline, and audit retention.
|
||||
- `tenant:coulomb` and future tenants may request scoped credentials only
|
||||
for registered tenant resources.
|
||||
- flex-auth decision envelopes must include tenant id, protected-system
|
||||
id, bucket or prefix, action set, TTL, assurance evidence, obligations,
|
||||
deny reasons, and audit correlation ids.
|
||||
- CARING descriptors must mark whether a request is platform-scoped or
|
||||
tenant-scoped; platform-scoped descriptor use is rare, reviewed, and
|
||||
auditable.
|
||||
- Topaz is the first delegated PDP runtime behind flex-auth. Its data and
|
||||
policy loading must not give a tenant administrator control over
|
||||
platform policies.
|
||||
- OpenBao may broker, lease, audit, or store temporary credential
|
||||
material after flex-auth approval. OpenBao must not become the source of
|
||||
object-storage authorization policy, and tenants must not receive
|
||||
OpenBao root tokens, unseal/recovery material, platform mounts, or
|
||||
global auth-method control.
|
||||
|
||||
## Tasks
|
||||
|
||||
```task
|
||||
id: NK-WP-0007-T1
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "3b50c48f-1ab2-4631-b176-d49d9d705f1e"
|
||||
```
|
||||
|
||||
Document the target architecture in
|
||||
`docs/object-storage-sts-credential-vending.md`, including actors,
|
||||
trust boundaries, token flow, policy decision flow, credential lease
|
||||
flow, and failure modes.
|
||||
|
||||
```task
|
||||
id: NK-WP-0007-T2
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "5b942d22-6f29-4975-88fb-e3e5bcaf4029"
|
||||
```
|
||||
|
||||
Define the flex-auth resource/action model for object storage:
|
||||
protected-system id, bucket resources, prefix resources, actions
|
||||
(`s3:GetObject`, `s3:PutObject`, `s3:DeleteObject`, listing,
|
||||
multipart operations), TTL limits, obligations, and deny reasons.
|
||||
|
||||
```task
|
||||
id: NK-WP-0007-T3
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "8d27e5b4-9bbb-4a53-a079-0df1047d755e"
|
||||
```
|
||||
|
||||
Define the IAM Profile requirements for credential vending:
|
||||
accepted issuers, audiences, service-account subjects, human/admin
|
||||
subjects, MFA/assurance claims, emergency principals, and local-dev
|
||||
issuer restrictions.
|
||||
|
||||
```task
|
||||
id: NK-WP-0007-T4
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "c0c4f297-6cff-419b-9ce3-be5537c92e93"
|
||||
```
|
||||
|
||||
Assess backend STS implementations and write a decision record covering
|
||||
Ceph RGW STS, MinIO/AIStor STS, AWS STS, Cloudflare R2 temporary
|
||||
credentials, and when OpenBao should broker, lease, audit, or store the
|
||||
resulting credential material.
|
||||
|
||||
```task
|
||||
id: NK-WP-0007-T5
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "ccb10b2d-6378-4824-90b1-c31bd882d93d"
|
||||
```
|
||||
|
||||
Prototype the smallest credential-vending interface: CLI or HTTP
|
||||
request shape, normalized response shape, lease metadata, audit event,
|
||||
OpenBao lease/audit metadata where used, and a
|
||||
`credential_process`-compatible option for SDK consumers.
|
||||
|
||||
```task
|
||||
id: NK-WP-0007-T6
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "63c6859b-980e-44da-a5a6-b92a8a3225dd"
|
||||
```
|
||||
|
||||
Create integration guidance for artifact-store and other consumers:
|
||||
environment variables, `AWS_SESSION_TOKEN`, refresh behavior, sidecar or
|
||||
controller refresh options, and prohibited patterns such as long-lived
|
||||
root access keys.
|
||||
|
||||
## Implementation Review - 2026-05-18
|
||||
|
||||
Implemented as architecture and decision artifacts:
|
||||
|
||||
- `docs/object-storage-sts-credential-vending.md` defines the target
|
||||
architecture, actors, trust boundaries, token flow, flex-auth
|
||||
vocabulary, IAM Profile requirements, backend assessment, OpenBao
|
||||
role, request/response prototype, audit event, failure modes, and
|
||||
consumer guidance.
|
||||
- `docs/adr/ADR-0008-object-storage-sts-credential-vending.md` records
|
||||
the decision to use a provider-neutral NetKingdom vending boundary with
|
||||
provider-native temporary credential mechanisms where possible.
|
||||
|
||||
The implementation deliberately stops before building a live vending
|
||||
service. Service implementation belongs in a follow-up workplan once
|
||||
artifact-store has session-token/refresh support and the Railiance
|
||||
OpenBao bootstrap/unseal/break-glass work is ready.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- NetKingdom has a canonical, provider-neutral pattern for object-storage
|
||||
STS credential vending.
|
||||
- flex-auth is the policy decision point for bucket/prefix/action/TTL
|
||||
authorization.
|
||||
- OpenBao is treated as runtime secret/lease infrastructure where useful,
|
||||
not as the canonical authorization policy engine.
|
||||
- key-cape and Keycloak are treated as IAM Profile implementations, not
|
||||
object-storage policy engines.
|
||||
- ops-warden and ops-bridge remain SSH/tunnel-specific but their
|
||||
short-lived credential lessons are reused where appropriate.
|
||||
- artifact-store has enough guidance to consume temporary credentials
|
||||
without owning the vending authority.
|
||||
@@ -0,0 +1,285 @@
|
||||
---
|
||||
id: NK-WP-0008
|
||||
type: workplan
|
||||
title: IT Security Architecture Patterns Infospace
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: done
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
planning_priority: high
|
||||
planning_order: 8
|
||||
created: 2026-05-17
|
||||
updated: 2026-05-19
|
||||
depends_on:
|
||||
- NK-WP-0006
|
||||
state_hub_workstream_id: "053c6d96-9396-40c9-a2e5-c36531e7810d"
|
||||
execution_repo: infospace-bench
|
||||
infospace_path: infospaces/patterns-of-it-securita-architecture---
|
||||
|
||||
# NK-WP-0008 - IT Security Architecture Patterns Infospace
|
||||
|
||||
## Goal
|
||||
|
||||
Create a curated infospace of reusable IT security architecture patterns
|
||||
for NetKingdom-enabled infrastructures.
|
||||
|
||||
The infospace should be a reference library of patterns, tradeoffs,
|
||||
threats, implementation variants, and canonical NetKingdom mappings. It
|
||||
should help us recognize patterns such as STS credential vending,
|
||||
workload identity, secret zero avoidance, break-glass access, delegated
|
||||
authorization, short-lived certificates, and policy-as-code before they
|
||||
become scattered repo-local folklore.
|
||||
|
||||
## Context
|
||||
|
||||
The platform now spans identity, MFA, policy, SSH certificates, reverse
|
||||
tunnels, object storage, artifact storage, Kubernetes platform services,
|
||||
and secrets management. Several patterns repeat across repos:
|
||||
|
||||
- key-cape and Keycloak implement OIDC identity contracts.
|
||||
- flex-auth implements policy-as-code authorization decisions.
|
||||
- ops-warden issues short-lived SSH certificates.
|
||||
- ops-bridge consumes short-lived SSH credentials and records actor
|
||||
attribution.
|
||||
- artifact-store consumes object storage and needs temporary S3
|
||||
credential support.
|
||||
- Railiance platform services need a canonical secrets manager and
|
||||
object-storage integration.
|
||||
|
||||
An infospace makes these repeatable architectural patterns explicit,
|
||||
searchable, comparable, and teachable.
|
||||
|
||||
## Seeded Infospace
|
||||
|
||||
Bernd seeded the working corpus in `infospace-bench`:
|
||||
|
||||
```text
|
||||
/home/worsch/infospace-bench/infospaces/patterns-of-it-securita-architecture/
|
||||
```
|
||||
|
||||
The current seed is:
|
||||
|
||||
```text
|
||||
genesis/InitialExploration.md
|
||||
```
|
||||
|
||||
That file already sketches the two intended collections: a security
|
||||
capability catalog and a security architecture pattern catalog, with
|
||||
readiness levels and mappings to standards such as NIST CSF, CIS, OWASP,
|
||||
SLSA, and OpenSSF.
|
||||
|
||||
NK-WP-0008 will therefore use `infospace-bench` as the canonical working
|
||||
space instead of creating a separate `docs/security-patterns/` tree in
|
||||
`net-kingdom`. `net-kingdom` remains the owner of the NetKingdom security
|
||||
architecture mapping; `infospace-bench` owns the concrete infospace
|
||||
artifact lifecycle, manifests, evaluation reports, and exports.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- promote the seeded directory into a valid `infospace-bench` infospace
|
||||
with `infospace.yaml`, `artifacts/index.yaml`, and the standard layout
|
||||
- import `genesis/InitialExploration.md` as the seed source artifact
|
||||
- define capability and pattern document templates inside the infospace
|
||||
- capture initial capability, pattern, readiness, and mapping artifacts
|
||||
- record source references and current product/tool options
|
||||
- connect patterns to implementation repos and workplans
|
||||
- distinguish canonical patterns from experiments and anti-patterns
|
||||
|
||||
Out of scope:
|
||||
|
||||
- implementing every pattern
|
||||
- building new lower-level `infospace-bench` engine features
|
||||
- replacing ADRs
|
||||
- duplicating vendor documentation
|
||||
- using `net-kingdom/docs/security-patterns/` as the primary corpus
|
||||
- writing full tutorials; tutorials are handled by NK-WP-0009
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 - Promote The Seed Into A Valid Infospace
|
||||
|
||||
```task
|
||||
id: NK-WP-0008-T1
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "d1b7213c-3315-49d2-90c9-efdf2bea3563"
|
||||
```
|
||||
|
||||
Promote
|
||||
`/home/worsch/infospace-bench/infospaces/patterns-of-it-securita-architecture`
|
||||
from a genesis note into a valid `infospace-bench` project: create
|
||||
`infospace.yaml`, `artifacts/index.yaml`, the required artifact/output
|
||||
directories, and a manifest entry for `genesis/InitialExploration.md`.
|
||||
|
||||
Define the initial artifact taxonomy for:
|
||||
|
||||
- capabilities
|
||||
- patterns
|
||||
- readiness levels
|
||||
- mappings
|
||||
- source references
|
||||
- generated reports
|
||||
|
||||
### T02 - Extract The Initial Capability And Pattern Catalogs
|
||||
|
||||
```task
|
||||
id: NK-WP-0008-T2
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "59966187-27f1-4b9c-9dfc-e59d11ff115c"
|
||||
```
|
||||
|
||||
Extract the first structured artifacts from the seeded exploration:
|
||||
|
||||
- a security capability catalog
|
||||
- a security architecture pattern catalog
|
||||
- readiness levels RL0-RL4
|
||||
- a production readiness baseline
|
||||
|
||||
Initial patterns must include STS credential vending, workload identity,
|
||||
secret zero avoidance, dynamic secrets, short-lived SSH certificates,
|
||||
delegated authorization, break-glass access, tenant isolation, central
|
||||
audit ledger, policy-as-code admission, and supply-chain provenance.
|
||||
|
||||
Each pattern artifact should use a repeatable template: problem, context,
|
||||
forces, solution, implementation sketch, failure modes, related
|
||||
capabilities, maturity, verification, and references.
|
||||
|
||||
### T03 - Map Patterns To NetKingdom And Ecosystem Ownership
|
||||
|
||||
```task
|
||||
id: NK-WP-0008-T3
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "927c08a5-1a7e-4634-a514-0f562e286708"
|
||||
```
|
||||
|
||||
Map each capability and pattern to the owning repos, components, and
|
||||
workplans:
|
||||
|
||||
- `net-kingdom`, NK-WP-0006, NK-WP-0007, NK-WP-0008, NK-WP-0009
|
||||
- `key-cape`, Keycloak, Authelia, LLDAP, privacyIDEA
|
||||
- `flex-auth`, Topaz, CARING descriptors, decision envelopes
|
||||
- `railiance-platform`, OpenBao, Ceph RGW, MinIO-compatible stores
|
||||
- `ops-warden`, `ops-bridge`, short-lived SSH and agent access
|
||||
- `artifact-store`, object storage, STS consumers, artifact integrity
|
||||
- relevant standards and references from the seed document
|
||||
|
||||
This mapping should distinguish platform ownership, product/application
|
||||
ownership, tenant responsibility, and external provider responsibility.
|
||||
|
||||
### T04 - Build The Index, Maturity Matrix, And Report
|
||||
|
||||
```task
|
||||
id: NK-WP-0008-T4
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "884626ea-243e-4806-9267-77ef643158b7"
|
||||
```
|
||||
|
||||
Create the first infospace index/report with capability status, pattern
|
||||
maturity, owning repo, implementation links, open decisions, and gaps.
|
||||
|
||||
The report should make it easy to answer:
|
||||
|
||||
- which patterns are canonical versus experimental
|
||||
- which patterns already have NetKingdom/Railiance implementation anchors
|
||||
- which patterns need ADRs, workplans, or tutorials
|
||||
- which patterns feed NK-WP-0009 tutorials
|
||||
|
||||
### T05 - Define Admission And Review Criteria
|
||||
|
||||
```task
|
||||
id: NK-WP-0008-T5
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "d3b29f3d-0da5-43b5-a93a-d95fb8a0ceef"
|
||||
```
|
||||
|
||||
Add review criteria for admitting new patterns: vendor neutrality,
|
||||
threat-model clarity, open-source/commercial implementation options,
|
||||
operability, auditability, failure-mode behavior, readiness-level fit,
|
||||
evidence quality, and ownership clarity.
|
||||
|
||||
Define when a pattern is allowed to graduate from:
|
||||
|
||||
```text
|
||||
seed -> draft -> reviewed -> canonical -> deprecated
|
||||
```
|
||||
|
||||
The criteria should be expressed as an infospace evaluation/checklist so
|
||||
future pattern additions can be reviewed consistently.
|
||||
|
||||
## Implementation Review - 2026-05-19
|
||||
|
||||
NK-WP-0008 has been implemented in `infospace-bench` at:
|
||||
|
||||
```text
|
||||
/home/worsch/infospace-bench/infospaces/patterns-of-it-securita-architecture/
|
||||
```
|
||||
|
||||
Created artifacts:
|
||||
|
||||
- `infospace.yaml`
|
||||
- `artifacts/index.yaml`
|
||||
- `artifacts/entities/security-capability-catalog.md`
|
||||
- `artifacts/entities/security-architecture-pattern-catalog.md`
|
||||
- `artifacts/entities/security-readiness-levels.md`
|
||||
- `artifacts/relations/netkingdom-ownership-map.md`
|
||||
- `artifacts/generated/security-pattern-index.md`
|
||||
- `artifacts/generated/pattern-admission-review.md`
|
||||
- `reports/initial-security-pattern-report.md`
|
||||
|
||||
Population pass:
|
||||
|
||||
- copied the NetKingdom object-storage STS credential-vending document,
|
||||
platform identity/security architecture document, ADR-0008, and
|
||||
Railiance OpenBao platform secrets service note into
|
||||
`artifacts/sources/`
|
||||
- added `artifacts/entities/capability-object-storage-access.md`
|
||||
- added `artifacts/entities/pattern-sts-credential-vending.md`
|
||||
- added `artifacts/relations/sts-credential-vending-relationship-map.md`
|
||||
- added `artifacts/generated/sts-credential-vending-extraction.md`
|
||||
- registered the new STS/OpenBao evidence, capability, pattern, relation
|
||||
map, extraction, index, and report edges in `artifacts/index.yaml`
|
||||
- normalized relationship direction so the infospace graph remains
|
||||
connected and acyclic
|
||||
|
||||
Catalogue population pass:
|
||||
|
||||
- added first-class pattern artifacts for the initial NetKingdom pattern
|
||||
set beyond STS credential vending: workload identity, secret zero
|
||||
avoidance, dynamic secrets, short-lived SSH certificates, delegated
|
||||
authorization, break-glass access, tenant isolation, central audit
|
||||
ledger, policy-as-code admission, supply-chain provenance, network
|
||||
default deny, object-level authorization check, human/agent identity
|
||||
split, and tenant context propagation
|
||||
- added `artifacts/generated/research-pattern-normalization.md` to map
|
||||
the broader `genesis/InitialExploration.md` research tables into the
|
||||
first-class pattern set and future promotion candidates
|
||||
- registered the pattern artifacts in `artifacts/index.yaml` with source
|
||||
seed, catalog inclusion, ownership map, admission review, readiness,
|
||||
and index summary relationships
|
||||
|
||||
Verification:
|
||||
|
||||
- `.venv/bin/python -m infospace_bench inspect infospaces/patterns-of-it-securita-architecture`
|
||||
- `.venv/bin/python -m infospace_bench validate infospaces/patterns-of-it-securita-architecture`
|
||||
- `.venv/bin/python -m infospace_bench metrics infospaces/patterns-of-it-securita-architecture` passed viability in snapshot `502d0933` with 16 artifacts, 100% coverage, one connected component, and zero consistency cycles
|
||||
- `.venv/bin/python -m infospace_bench graph infospaces/patterns-of-it-securita-architecture --format mermaid`
|
||||
- `.venv/bin/python -m pytest` passed with 179 passed, 2 skipped
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- `infospace-bench/infospaces/patterns-of-it-securita-architecture/`
|
||||
is a valid infospace-bench project with a manifest and standard layout.
|
||||
- Initial high-value security patterns are documented in a consistent
|
||||
shape.
|
||||
- Each pattern names the canonical NetKingdom mapping and the repos that
|
||||
own implementation.
|
||||
- The infospace distinguishes patterns, tutorials, ADRs, and vendor docs.
|
||||
- State Hub task titles and descriptions reflect the concrete
|
||||
infospace-bench workflow instead of generic placeholder task names.
|
||||
@@ -0,0 +1,352 @@
|
||||
---
|
||||
id: NK-WP-0010
|
||||
type: workplan
|
||||
title: Genesis Security Pattern Completion
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
planning_priority: medium
|
||||
planning_order: 10
|
||||
created: 2026-05-19
|
||||
updated: 2026-05-19
|
||||
depends_on:
|
||||
- NK-WP-0008
|
||||
unblocks:
|
||||
- NK-WP-0009
|
||||
execution_repo: infospace-bench
|
||||
infospace_path: infospaces/patterns-of-it-securita-architecture
|
||||
state_hub_workstream_id: "f4faf8b4-ae57-40cf-a881-6fe66ca6ad74"
|
||||
---
|
||||
|
||||
# NK-WP-0010 - Genesis Security Pattern Completion
|
||||
|
||||
## Goal
|
||||
|
||||
Promote every security architecture and solution pattern explicitly
|
||||
named in
|
||||
`/home/worsch/infospace-bench/infospaces/patterns-of-it-securita-architecture/genesis/InitialExploration.md`
|
||||
into a first-class infospace artifact.
|
||||
|
||||
NK-WP-0008 created the infospace and populated the first NetKingdom
|
||||
pattern set. NK-WP-0010 closes the remaining catalogue gap: no pattern
|
||||
mentioned in the genesis research should remain only as prose inside the
|
||||
source note or as a candidate row in the normalization artifact.
|
||||
|
||||
## Context
|
||||
|
||||
The genesis file names a broad security pattern catalogue across seven
|
||||
families:
|
||||
|
||||
- identity and access
|
||||
- tenant isolation
|
||||
- Kubernetes and platform
|
||||
- secrets and cryptography
|
||||
- application/API security
|
||||
- supply chain
|
||||
- detection and response
|
||||
|
||||
NK-WP-0008 already created first-class artifacts for the NetKingdom
|
||||
initial pattern set, including STS credential vending, workload
|
||||
identity, secret zero avoidance, dynamic secrets, short-lived SSH
|
||||
certificates, delegated authorization, break-glass access, tenant
|
||||
isolation, central audit ledger, policy-as-code admission, supply-chain
|
||||
provenance, network default deny, object-level authorization,
|
||||
human/agent identity split, and tenant context propagation.
|
||||
|
||||
This workplan should complete the literal genesis coverage while keeping
|
||||
the distinction between:
|
||||
|
||||
- an exact pattern named by the research seed
|
||||
- a NetKingdom canonical pattern
|
||||
- an umbrella pattern that groups several exact seed patterns
|
||||
- a future tutorial candidate for NK-WP-0009
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- create or reconcile one first-class artifact for each exact pattern
|
||||
name in the genesis security architecture pattern catalogue
|
||||
- keep existing NK-WP-0008 pattern artifacts, adding aliases or related
|
||||
links instead of duplicating them where an exact seed pattern is
|
||||
already represented
|
||||
- update `artifacts/index.yaml` with source, catalogue, ownership,
|
||||
admission, readiness, index, and report relationships
|
||||
- update `artifacts/generated/research-pattern-normalization.md` so it
|
||||
becomes a completion map rather than a candidate-only map
|
||||
- update the generated index, report, and ownership map
|
||||
- preserve an acyclic, connected infospace graph
|
||||
|
||||
Out of scope:
|
||||
|
||||
- writing tutorials; that remains NK-WP-0009
|
||||
- implementing platform services
|
||||
- resolving every open architecture decision in the pattern artifacts
|
||||
- replacing ADRs or vendor docs
|
||||
|
||||
## Genesis Pattern Inventory
|
||||
|
||||
This workplan targets the exact pattern names in the genesis file:
|
||||
|
||||
| Family | Patterns |
|
||||
| --- | --- |
|
||||
| Identity and access | Central Identity Provider; Identity Broker; Tenant Membership Boundary; Role Composition; Policy Decision Point / Policy Enforcement Point; Time-boxed Privilege Elevation; Break-glass Access; Human/Agent Identity Split |
|
||||
| Tenant isolation | Namespace-per-Tenant; Cluster-per-Tenant; Cell-based Architecture; Shared Control Plane, Isolated Data Plane; Tenant Context Propagation; Tenant Data Partitioning |
|
||||
| Kubernetes and platform | Secure Cluster Baseline; Policy-as-Code Admission Control; Pod Security Baseline/Restricted; Network Default Deny; Signed Image Admission; GitOps with Guardrails; Runtime Threat Detection |
|
||||
| Secrets and cryptography | External Secrets Operator; Sealed Secret / Encrypted Git Secret; Short-lived Credentials; Key-per-Tenant; Certificate Automation |
|
||||
| Application/API security | API Gateway as Security Boundary; Backend-for-Frontend; Object-Level Authorization Check; Schema-First API Security; Idempotent Command API; Secure File Upload Pipeline |
|
||||
| Supply chain | Protected Main Branch; Dependency Update Bot; SBOM-per-Release; SLSA Build Provenance; Signed Container Images; Quarantined Build Runner |
|
||||
| Detection and response | Security Event Taxonomy; Central Audit Ledger; Tenant Audit Log View; Incident Runbook Library; Kill Switch / Tenant Freeze; Token Revocation Sweep |
|
||||
|
||||
## Tasks
|
||||
|
||||
### T01 - Reconcile The Genesis Inventory
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T1
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "61160df5-7305-4a0f-a34d-2a763c29eab4"
|
||||
```
|
||||
|
||||
Create a completion matrix from `genesis/InitialExploration.md` that
|
||||
lists every exact seed pattern, current artifact coverage, aliases,
|
||||
canonical NetKingdom mapping, owner, status, and whether a new artifact
|
||||
is needed.
|
||||
|
||||
Update `artifacts/generated/research-pattern-normalization.md` so it
|
||||
becomes the authoritative inventory for this workplan.
|
||||
|
||||
### T02 - Complete Identity And Access Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T2
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "dad43681-9404-47b8-b58c-39b7218c2542"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- Central Identity Provider
|
||||
- Identity Broker
|
||||
- Tenant Membership Boundary
|
||||
- Role Composition
|
||||
- Policy Decision Point / Policy Enforcement Point
|
||||
- Time-boxed Privilege Elevation
|
||||
- Break-glass Access
|
||||
- Human/Agent Identity Split
|
||||
|
||||
Existing break-glass and human/agent identity artifacts should be
|
||||
retained and enriched. The PDP/PEP artifact may reference the existing
|
||||
delegated authorization artifact, but the exact seed pattern must be
|
||||
discoverable as a first-class artifact or explicit alias.
|
||||
|
||||
### T03 - Complete Tenant Isolation Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T3
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "dee39f82-aa3a-4824-ba61-7fbdbd5c3d21"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- Namespace-per-Tenant
|
||||
- Cluster-per-Tenant
|
||||
- Cell-based Architecture
|
||||
- Shared Control Plane, Isolated Data Plane
|
||||
- Tenant Context Propagation
|
||||
- Tenant Data Partitioning
|
||||
|
||||
Ensure these link to the existing tenant isolation and tenant context
|
||||
propagation artifacts without flattening their different isolation
|
||||
strengths and failure modes.
|
||||
|
||||
### T04 - Complete Kubernetes And Platform Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T4
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "19def7b4-4f1a-45ad-b15b-6a56e675be41"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- Secure Cluster Baseline
|
||||
- Policy-as-Code Admission Control
|
||||
- Pod Security Baseline/Restricted
|
||||
- Network Default Deny
|
||||
- Signed Image Admission
|
||||
- GitOps with Guardrails
|
||||
- Runtime Threat Detection
|
||||
|
||||
Preserve the relationship to Railiance platform responsibilities,
|
||||
admission policy, pod security, image provenance, network segmentation,
|
||||
and detection coverage.
|
||||
|
||||
### T05 - Complete Secrets And Cryptography Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T5
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "622c3bbe-77a7-4049-b6f4-0cd1f54f3783"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- External Secrets Operator
|
||||
- Sealed Secret / Encrypted Git Secret
|
||||
- Short-lived Credentials
|
||||
- Key-per-Tenant
|
||||
- Certificate Automation
|
||||
|
||||
Link these to OpenBao, secret-zero avoidance, dynamic secrets, STS
|
||||
credential vending, credential bootstrap, tenant isolation, and
|
||||
certificate lifecycle ownership.
|
||||
|
||||
### T06 - Complete Application And API Security Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T6
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "e792f598-4dfc-4598-ba86-facd13cd8a12"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- API Gateway as Security Boundary
|
||||
- Backend-for-Frontend
|
||||
- Object-Level Authorization Check
|
||||
- Schema-First API Security
|
||||
- Idempotent Command API
|
||||
- Secure File Upload Pipeline
|
||||
|
||||
Ensure each artifact names where platform responsibility ends and
|
||||
product/application responsibility begins.
|
||||
|
||||
### T07 - Complete Supply-Chain Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T7
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "a43b189a-d1b4-4692-94d7-9c7e140808ca"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- Protected Main Branch
|
||||
- Dependency Update Bot
|
||||
- SBOM-per-Release
|
||||
- SLSA Build Provenance
|
||||
- Signed Container Images
|
||||
- Quarantined Build Runner
|
||||
|
||||
Relate these to artifact-store, signed image admission, policy-as-code
|
||||
admission, build provenance, SBOM storage, and release evidence.
|
||||
|
||||
### T08 - Complete Detection And Response Patterns
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T8
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "78a2d242-5a56-40a7-8499-ba7c72150700"
|
||||
```
|
||||
|
||||
Create or reconcile first-class artifacts for:
|
||||
|
||||
- Security Event Taxonomy
|
||||
- Central Audit Ledger
|
||||
- Tenant Audit Log View
|
||||
- Incident Runbook Library
|
||||
- Kill Switch / Tenant Freeze
|
||||
- Token Revocation Sweep
|
||||
|
||||
Retain the existing central audit ledger artifact and add explicit
|
||||
patterns for event classification, tenant-visible projections,
|
||||
response playbooks, containment, and credential revocation.
|
||||
|
||||
### T09 - Refresh Relationships, Indexes, And Reports
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T9
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "8ec9bc00-1f7b-4f34-b02e-33fdacda9da5"
|
||||
```
|
||||
|
||||
Update the infospace manifest and narrative artifacts:
|
||||
|
||||
- `artifacts/index.yaml`
|
||||
- `artifacts/entities/security-architecture-pattern-catalog.md`
|
||||
- `artifacts/relations/netkingdom-ownership-map.md`
|
||||
- `artifacts/generated/security-pattern-index.md`
|
||||
- `artifacts/generated/pattern-admission-review.md`
|
||||
- `artifacts/generated/research-pattern-normalization.md`
|
||||
- `reports/initial-security-pattern-report.md`
|
||||
|
||||
The final graph must remain connected and acyclic.
|
||||
|
||||
### T10 - Verify Completion And Feed NK-WP-0009
|
||||
|
||||
```task
|
||||
id: NK-WP-0010-T10
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "a5449bc6-8529-4350-822b-7c758bf790cb"
|
||||
```
|
||||
|
||||
Run the infospace verification suite:
|
||||
|
||||
- `.venv/bin/python -m infospace_bench validate infospaces/patterns-of-it-securita-architecture`
|
||||
- `.venv/bin/python -m infospace_bench metrics infospaces/patterns-of-it-securita-architecture`
|
||||
- `.venv/bin/python -m infospace_bench graph infospaces/patterns-of-it-securita-architecture --format mermaid`
|
||||
- `.venv/bin/python -m pytest`
|
||||
|
||||
Update State Hub progress, mark completed tasks, and add a handoff note
|
||||
for NK-WP-0009 identifying which completed patterns should become
|
||||
tutorials first.
|
||||
|
||||
## Implementation Evidence
|
||||
|
||||
Completed on 2026-05-19 in
|
||||
`/home/worsch/infospace-bench/infospaces/patterns-of-it-securita-architecture`.
|
||||
|
||||
- Promoted all 44 exact genesis pattern names into first-class pattern
|
||||
artifacts or retained exact existing artifacts.
|
||||
- Preserved the nine NetKingdom umbrella/canonical pattern artifacts
|
||||
created by NK-WP-0008 and linked them to the exact seed patterns.
|
||||
- Refreshed `artifacts/index.yaml`, the pattern catalog, ownership map,
|
||||
security pattern index, admission review, normalization matrix, and
|
||||
initial report.
|
||||
- Verification passed:
|
||||
- `.venv/bin/python -m infospace_bench validate infospaces/patterns-of-it-securita-architecture`
|
||||
- `.venv/bin/python -m infospace_bench metrics infospaces/patterns-of-it-securita-architecture`
|
||||
with snapshot `7bf35f3b`, 69 artifacts, one connected component,
|
||||
zero cycles, coverage `1.0`, and viability passed.
|
||||
- `.venv/bin/python -m infospace_bench graph infospaces/patterns-of-it-securita-architecture --format mermaid`
|
||||
- `.venv/bin/python -m pytest` with 181 passed and 2 skipped.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Every exact pattern name from the genesis pattern catalogue is
|
||||
discoverable as a first-class artifact or explicit alias in the
|
||||
infospace.
|
||||
- `research-pattern-normalization.md` shows no unaccounted seed
|
||||
patterns.
|
||||
- The manifest registers all pattern artifacts and relationships.
|
||||
- The generated index and report identify canonical, draft, seed, and
|
||||
promotion-candidate patterns.
|
||||
- `infospace_bench validate` passes.
|
||||
- `infospace_bench metrics` passes viability with one connected
|
||||
component and zero consistency cycles.
|
||||
- NK-WP-0009 has a clear tutorial-priority handoff from the completed
|
||||
pattern library.
|
||||
@@ -0,0 +1,222 @@
|
||||
---
|
||||
id: NK-WP-0012
|
||||
type: workplan
|
||||
title: "NetKingdom IAM Profile Specification"
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: worsch
|
||||
topic_slug: netkingdom
|
||||
planning_priority: high
|
||||
planning_order: 12
|
||||
created: "2026-05-21"
|
||||
updated: "2026-05-22"
|
||||
depends_on:
|
||||
- NK-WP-0006
|
||||
state_hub_workstream_id: 9b8e4afc-eb71-47d9-8750-799a082b320a
|
||||
enables:
|
||||
- NK-WP-0011---
|
||||
|
||||
# NK-WP-0012 — NetKingdom IAM Profile Specification
|
||||
|
||||
> The IAM Profile is referenced everywhere as "the contract all applications
|
||||
> target," but it does not exist as a net-kingdom artifact. A draft **v0.1
|
||||
> exists in the-custodian canon** (`canon/standards/iam-profile_v0.1.md`),
|
||||
> scoped "all-hubs" and Custodian-flavored. SCOPE.md says net-kingdom owns
|
||||
> the IAM Profile. This workplan resolves that: net-kingdom becomes the
|
||||
> canonical owner, and the profile is made provider-neutral, tenant- and
|
||||
> agent-aware, and conformance-testable.
|
||||
|
||||
## Goal
|
||||
|
||||
Produce the **canonical, versioned NetKingdom IAM Profile** in net-kingdom
|
||||
canon — the OIDC/PKCE contract every implementation issues and every
|
||||
application and the authorization layer consume — together with an
|
||||
**executable conformance check**.
|
||||
|
||||
The profile is the contract that makes the rest of the architecture
|
||||
coherent:
|
||||
|
||||
- it is what `key-cape` (lightweight) and Keycloak (expanded) each
|
||||
implement, interchangeably (capability ladder C1/C5);
|
||||
- it is the identity input `flex-auth` consumes for authorization
|
||||
decisions (responsibility map: the identity layer owns the claim
|
||||
contract — that contract is this profile);
|
||||
- it is the thing **NK-WP-0011-T6** runs conformance checks against, so
|
||||
this workplan **enables** NK-WP-0011.
|
||||
|
||||
## Why now / what exists
|
||||
|
||||
The v0.1 draft is a strong base — discovery contract, Authorization Code +
|
||||
PKCE human flow, service-account flow, required claims, token lifecycle,
|
||||
emergency/break-glass, and a local-development profile. But it has gaps for
|
||||
the current architecture:
|
||||
|
||||
| Gap in v0.1 | Needed because |
|
||||
|---|---|
|
||||
| Lives in the-custodian, scoped "all-hubs" | net-kingdom owns the profile (SCOPE.md, responsibility map) |
|
||||
| Keycloak named as *the* reference provider | provider-neutral now: key-cape lightweight / Keycloak expanded are interchangeable implementations |
|
||||
| Scope/role vocabulary is hub-specific (`hub:*`, `ops:*`, `fin:*`) | the core profile must be platform-neutral; hub/app scopes are downstream extensions |
|
||||
| No tenant claim | recursive `tenant:platform` vs tenant model (NK-WP-0006) needs tenant in the token |
|
||||
| Only human/service identities | architecture distinguishes human / service / **agent** principals |
|
||||
| Assurance is implicit | flex-auth decision envelopes require explicit assurance evidence |
|
||||
| No executable conformance check | NK-WP-0011-T6 and every implementation need a runnable contract test |
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- ownership and reconciliation decision (ADR) with the-custodian v0.1
|
||||
- a provider-neutral, platform-neutral **v0.2** profile in net-kingdom canon
|
||||
- tenant- and agent-aware claims, and explicit assurance evidence
|
||||
- the identity→authorization claim contract consumed by flex-auth
|
||||
- an executable conformance check
|
||||
- versioning and breaking-change governance for the profile
|
||||
- migration of downstream references to the canonical net-kingdom spec
|
||||
|
||||
Out of scope:
|
||||
|
||||
- implementing the profile in key-cape or Keycloak (their repos own that)
|
||||
- defining tenant- or application-specific scope vocabularies
|
||||
- deploying any identity provider
|
||||
|
||||
## Tasks
|
||||
|
||||
```task
|
||||
id: NK-WP-0012-T1
|
||||
state_hub_task_id: 284dda38-b778-445a-a7dc-9b5a12fa380f
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Ownership & reconciliation decision (ADR-0011).** Record that net-kingdom
|
||||
is the canonical owner of the IAM Profile. Decide how the-custodian's
|
||||
all-hubs v0.1 reconciles: net-kingdom owns the **core/platform profile**;
|
||||
hub- and app-specific scope vocabularies (`hub:*`, `ops:*`, `fin:*`) become
|
||||
**downstream extensions** that map back to the core, not part of it. Define
|
||||
the profile's **versioning and breaking-change governance** (what a
|
||||
breaking change is, how downstream is notified, how versions coexist).
|
||||
|
||||
```task
|
||||
id: NK-WP-0012-T2
|
||||
state_hub_task_id: 0070398d-b0a4-4c11-a6fa-000166e1108f
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Author IAM Profile v0.2 (provider-neutral core).** Create
|
||||
`canon/standards/iam-profile_v0.2.md` in net-kingdom. Carry forward the
|
||||
solid v0.1 material — discovery contract, Authorization Code + PKCE human
|
||||
flow, service-account flow, required/recommended claims, token lifecycle,
|
||||
emergency/break-glass, local-development profile — and make it
|
||||
**provider-neutral**: key-cape (lightweight) and Keycloak (expanded) are
|
||||
named as interchangeable implementations, neither as "the" reference.
|
||||
Remove hub-specific vocabulary from the core.
|
||||
|
||||
```task
|
||||
id: NK-WP-0012-T3
|
||||
state_hub_task_id: 6fc2a5e1-1480-42f1-86a2-3e714359e1ba
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Extend for the recursive and agent model.** Add a **tenant** claim
|
||||
(`tenant:platform` vs tenant id), formalize the **human / service / agent**
|
||||
principal types and how each is represented, and define an explicit
|
||||
**assurance evidence** claim (how authentication strength / MFA is conveyed
|
||||
in the token). Align with NK-WP-0006 and the responsibility map.
|
||||
|
||||
```task
|
||||
id: NK-WP-0012-T4
|
||||
state_hub_task_id: 0e52ed45-afa7-4832-9d6a-1ebbbab43872
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Define the identity→authorization claim contract.** Specify exactly which
|
||||
claims the profile guarantees as inputs to flex-auth decision envelopes —
|
||||
subject, issuer, audience, tenant, groups, roles, scopes, assurance — so
|
||||
flex-auth treats the profile as normative input and never re-derives
|
||||
identity. This is the contract named in the responsibility map.
|
||||
|
||||
```task
|
||||
id: NK-WP-0012-T5
|
||||
state_hub_task_id: f0a62e77-b781-4625-b8bd-d191b48af58e
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Executable conformance check.** Build a runnable suite that validates an
|
||||
issuer/implementation against the profile: discovery document completeness,
|
||||
PKCE enforcement, claim shape, JWKS and key-rotation tolerance, token
|
||||
validation (issuer/audience/expiry/signature), and rejection of
|
||||
local-development issuers in production. This is the artifact NK-WP-0011-T6
|
||||
consumes; it must run against both a key-cape and a Keycloak issuer.
|
||||
|
||||
```task
|
||||
id: NK-WP-0012-T6
|
||||
state_hub_task_id: a1fd53a9-526f-4d87-89db-6073710c885d
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
**Migration & cross-references.** Supersede or relink the-custodian v0.1
|
||||
(deprecation note pointing at the net-kingdom canonical spec), and update
|
||||
downstream references — `key-cape` and `flex-auth` interface docs,
|
||||
NK-WP-0011, and any architecture docs — to cite the canonical net-kingdom
|
||||
profile. Per ADR-0010, downstream **intents** are not touched; only
|
||||
interface/reference docs.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- The canonical IAM Profile lives in net-kingdom canon, versioned, and an
|
||||
ADR records ownership and the reconciliation with the-custodian v0.1.
|
||||
- The core profile is provider-neutral and platform-neutral (no
|
||||
hub-specific scopes in the core; no single "reference provider").
|
||||
- The profile carries tenant, principal-type (human/service/agent), and
|
||||
assurance claims, aligned with the recursive model.
|
||||
- The claims flex-auth consumes are specified as a normative contract.
|
||||
- An executable conformance check exists and passes against both a
|
||||
key-cape and a Keycloak issuer.
|
||||
- Versioning and breaking-change governance is documented.
|
||||
- Downstream reference docs point at the canonical spec; the custodian v0.1
|
||||
carries a deprecation/relocation note.
|
||||
|
||||
## Completion Notes
|
||||
|
||||
- ADR: `docs/adr/ADR-0011-iam-profile-ownership-and-version-governance.md`
|
||||
- Canonical profile: `canon/standards/iam-profile_v0.2.md`
|
||||
- Executable conformance suite:
|
||||
`tools/iam-profile-conformance/iam_profile_conformance.py`
|
||||
- Fixture tests cover key-cape-like and Keycloak-like issuers, local-dev
|
||||
rejection in production mode, tenant claim enforcement, provider-native
|
||||
role normalization warnings, and delegated-agent claim shape.
|
||||
- Cross-repo reference docs updated without touching downstream
|
||||
`INTENT.md`: key-cape README/spec references now point at v0.2, and
|
||||
flex-auth consumption docs plus claim fixtures now include v0.2 tenant,
|
||||
principal, and assurance inputs.
|
||||
|
||||
## Dependencies & Sequencing
|
||||
|
||||
- **Depends on NK-WP-0006** for the recursive tenant model the claims encode.
|
||||
- **Enables NK-WP-0011** — T6 (IAM Profile conformance) cannot pass without
|
||||
the spec and the conformance check from this workplan. NK-WP-0012 should
|
||||
land before NK-WP-0011-T6.
|
||||
- Coordinates with **flex-auth** (the consumed claim contract, T4) and with
|
||||
**key-cape**/**Keycloak** as the implementations the conformance check
|
||||
runs against — those repos implement, this workplan specifies and tests.
|
||||
|
||||
## Resolved Questions
|
||||
|
||||
- Canonical role claim: `roles` is canonical. `realm_access.roles` is a
|
||||
transitional/provider-native source that must be mapped before
|
||||
production consumption.
|
||||
- Audience granularity: the core profile requires the receiving service
|
||||
in `aud`; endpoint/resource granularity belongs to flex-auth
|
||||
resource/action policy.
|
||||
- Agent principals differ from service accounts through
|
||||
`principal_type: agent`, an `agent` object, and delegated actor context
|
||||
(`actor_sub` or `act.sub`) when applicable.
|
||||
- The conformance check is a standalone tool in net-kingdom for v0.2.
|
||||
Other repos consume it as an executable contract rather than importing
|
||||
a shared library for now.
|
||||
@@ -0,0 +1,214 @@
|
||||
---
|
||||
id: NK-WP-0013
|
||||
type: workplan
|
||||
title: "Playbook Capability Contract"
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: worsch
|
||||
topic_slug: netkingdom
|
||||
planning_priority: high
|
||||
planning_order: 13
|
||||
created: "2026-05-21"
|
||||
updated: "2026-05-22"
|
||||
depends_on:
|
||||
- NK-WP-0006
|
||||
state_hub_workstream_id: 32a54d8e-8633-42a6-8ec1-104842c581c1
|
||||
---
|
||||
|
||||
# NK-WP-0013 — Playbook Capability Contract
|
||||
|
||||
> The **orchestration-layer analog of the IAM Profile**. ADR-0007's
|
||||
> meta-orchestration refinement named this as a prerequisite: for NetKingdom
|
||||
> to select and parametrize playbooks reliably, each Railiance playbook must
|
||||
> publish a **declared interface** — the capability it provisions, its
|
||||
> parameters (with defaults and constraints), and the responsibility it
|
||||
> claims. Without it, meta-orchestration composes against implicit behavior
|
||||
> and breaks silently when a playbook changes. This workplan defines that
|
||||
> contract.
|
||||
|
||||
## Goal
|
||||
|
||||
Define the **Playbook Capability Contract** — the schema and vocabulary by
|
||||
which a playbook declares:
|
||||
|
||||
1. **what capability it provisions** (controlled vocabulary, aligned to the
|
||||
capability ladder and the responsibility-map resource kinds),
|
||||
2. **its parameters** — name, type, default, constraints, required/optional,
|
||||
and which are security-sensitive, and
|
||||
3. **the responsibility it claims** — which element owns which resources, and
|
||||
which trust state(s) / readiness checks it satisfies or requires.
|
||||
|
||||
…plus the **catalog/consumption model** NetKingdom meta-orchestration uses
|
||||
to select, parametrize, and build a responsibility map for a scenario, and a
|
||||
**conformance validator** for declarations.
|
||||
|
||||
## Ownership (the boundary this realizes)
|
||||
|
||||
By symmetry with the IAM Profile, the **consumer that needs a stable
|
||||
interface defines the contract; the provider conforms**:
|
||||
|
||||
| | Contract owner | Publishes conformant declarations | Consumer |
|
||||
|---|---|---|---|
|
||||
| Identity | NetKingdom (IAM Profile) | key-cape / Keycloak | apps, flex-auth |
|
||||
| Orchestration | **NetKingdom (this contract)** | Railiance playbooks | NetKingdom meta-orchestration |
|
||||
|
||||
NetKingdom owns the contract schema; Railiance owns the playbooks and
|
||||
publishes one declaration per playbook; **execution stays in Railiance**
|
||||
(ADR-0007 unchanged). The contract makes a playbook change a versioned event
|
||||
rather than a silent break.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- ownership & boundary decision (ADR) and contract versioning governance
|
||||
- the capability vocabulary a declaration draws from
|
||||
- the parameter declaration format (defaults, constraints, sensitivity)
|
||||
- the responsibility-claim and trust-state/readiness format
|
||||
- the catalog and the meta-orchestration consumption model
|
||||
- a conformance validator for declarations
|
||||
- coordinated adoption proof with one reference Railiance playbook
|
||||
|
||||
Out of scope:
|
||||
|
||||
- authoring the playbooks themselves (Railiance owns execution)
|
||||
- writing declarations for every existing playbook (Railiance work; this
|
||||
workplan proves the contract with one reference declaration)
|
||||
- a dedicated execution-orchestration repo (deferred per ADR-0007)
|
||||
|
||||
## Tasks
|
||||
|
||||
```task
|
||||
id: NK-WP-0013-T1
|
||||
state_hub_task_id: d40f8b29-e983-4d52-bc1f-5f1c51709e7d
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Ownership & boundary decision (ADR-0012).** Record that NetKingdom owns
|
||||
the Playbook Capability Contract schema (consumer-defines-contract, IAM
|
||||
Profile precedent), Railiance authors playbooks and publishes conformant
|
||||
declarations, and execution stays in Railiance (ADR-0007). Decide whether
|
||||
the contract is NetKingdom-owned outright or NetKingdom-owned with Railiance
|
||||
co-design. Define contract **versioning and breaking-change governance**.
|
||||
|
||||
```task
|
||||
id: NK-WP-0013-T2
|
||||
state_hub_task_id: ece4b5b1-e1c2-449d-b0f4-83b7010bc838
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Capability vocabulary.** Define the controlled vocabulary of capabilities
|
||||
a playbook can declare it provisions, aligned to the **capability ladder
|
||||
(C0–C6)** and the **responsibility-map resource kinds** (identities,
|
||||
roles/scopes/policies, secrets/credentials, infrastructure resources). This
|
||||
is what "capability" means in a declaration, so two playbooks providing the
|
||||
same capability are comparable.
|
||||
|
||||
```task
|
||||
id: NK-WP-0013-T3
|
||||
state_hub_task_id: c956f4a8-b9fa-44ab-8174-31999b98e3b1
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Parameter declaration format.** Define how a playbook declares its
|
||||
parameters: name, type, **default**, **constraints** (allowed values /
|
||||
ranges), required vs optional, and a **security-sensitivity** marker so
|
||||
NetKingdom knows which parameters it may tune versus which are
|
||||
security-critical and constrained. This is what makes "parametrize where
|
||||
adequate" safe rather than guesswork.
|
||||
|
||||
```task
|
||||
id: NK-WP-0013-T4
|
||||
state_hub_task_id: e7de05a6-528a-4213-b6db-2c2e90353996
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Responsibility-claim & trust-state format.** Define how a declaration
|
||||
states which element **owns which resources** (feeding the responsibility
|
||||
map) and which **trust state(s) / readiness checks** (ADR-0007 model) it
|
||||
satisfies or requires. This lets NetKingdom assemble a coherent
|
||||
responsibility map and sequence for a scenario from the declarations.
|
||||
|
||||
```task
|
||||
id: NK-WP-0013-T5
|
||||
state_hub_task_id: 05a2ff7d-86c4-4de9-9ea8-39a9ad5352a8
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
**Catalog, consumption model, and conformance validator.** Define how
|
||||
declarations are published and discovered (the catalog), how
|
||||
meta-orchestration consumes them to **select**, **parametrize**, and build a
|
||||
**responsibility map** for a scenario, and a **conformance validator** that
|
||||
checks a declaration against the contract (the orchestration-layer analog of
|
||||
the IAM Profile conformance check, NK-WP-0012-T5).
|
||||
|
||||
```task
|
||||
id: NK-WP-0013-T6
|
||||
state_hub_task_id: 769ed490-c091-41c1-b2e2-e8e378470b6b
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
**Reference adoption with Railiance.** Coordinate with Railiance to have
|
||||
**one reference playbook publish a conformant declaration end-to-end**, and
|
||||
demonstrate NetKingdom selecting + parametrizing it from the declaration
|
||||
alone. Proves the contract is sufficient and is the template for adopting
|
||||
the rest. Cross-repo coordination item for the Railiance domain.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- An ADR records contract ownership, the Railiance-publishes/NetKingdom-
|
||||
consumes split, and ADR-0007 is confirmed unchanged.
|
||||
- The contract specifies capability vocabulary, parameter format (defaults,
|
||||
constraints, sensitivity), and responsibility/trust-state claims.
|
||||
- A catalog/consumption model and a declaration conformance validator exist.
|
||||
- At least one Railiance playbook publishes a conformant declaration, and
|
||||
NetKingdom composes and parametrizes it from that declaration alone.
|
||||
- Contract versioning and breaking-change governance is documented.
|
||||
|
||||
## Completion Notes
|
||||
|
||||
- ADR: `docs/adr/ADR-0012-playbook-capability-contract-ownership.md`
|
||||
- Canonical contract:
|
||||
`canon/standards/playbook-capability-contract_v0.1.md`
|
||||
- Machine-readable schema:
|
||||
`canon/schemas/playbook-capability-declaration_v0.1.schema.json`
|
||||
- Validator and composition demo:
|
||||
`tools/playbook-capability-contract/playbook_contract_validator.py`
|
||||
- Reference Railiance declaration:
|
||||
`../railiance-infra/capabilities/playbooks/railiance-infra.bootstrap-host.yaml`
|
||||
- Sample scenario:
|
||||
`examples/playbook-capability-contract/scenario-s1-host-bootstrap.yaml`
|
||||
- Fixture tests cover valid declarations, controlled vocabulary failures,
|
||||
forbidden tenant overrides, missing required parameters, and successful
|
||||
selection/parameter composition.
|
||||
|
||||
## Dependencies & Sequencing
|
||||
|
||||
- **Realizes** the playbook-contract dependency from ADR-0007's
|
||||
meta-orchestration refinement; does not change ADR-0007.
|
||||
- **Depends on NK-WP-0006** for the trust-state model and the
|
||||
responsibility-map resource kinds the declarations reference.
|
||||
- **Coordinates with the Railiance domain** — NetKingdom defines the
|
||||
contract; Railiance publishes declarations (T6) and continues to own
|
||||
execution.
|
||||
- Parallels NK-WP-0012: same consumer-defines-contract pattern, same
|
||||
conformance-check shape, applied to orchestration instead of identity.
|
||||
|
||||
## Resolved Questions
|
||||
|
||||
- Contract format and home: NetKingdom canon standard plus a
|
||||
machine-readable JSON schema and standalone validator.
|
||||
- Catalog mechanism: v0.1 uses file convention
|
||||
`capabilities/playbooks/*.yaml`; a registry can be layered on later.
|
||||
- Parameter sensitivity: tenant scenarios cannot override
|
||||
`platform_only`, `forbidden`, `playbook_default`,
|
||||
`security_sensitive`, or `secret_reference` parameters.
|
||||
- Validator form: standalone NetKingdom tool for v0.1, mirroring
|
||||
NK-WP-0012's executable-contract pattern.
|
||||
@@ -0,0 +1,181 @@
|
||||
---
|
||||
id: NK-WP-0014
|
||||
type: workplan
|
||||
title: "User Engine Preparation And Boundary Contracts"
|
||||
domain: infotech
|
||||
repo: net-kingdom
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: netkingdom
|
||||
planning_priority: high
|
||||
planning_order: 14
|
||||
created: "2026-05-22"
|
||||
updated: "2026-05-22"
|
||||
depends_on:
|
||||
- NK-WP-0012
|
||||
- NK-WP-0013
|
||||
state_hub_workstream_id: "b9bf56bc-7ef6-43eb-badc-fa0f4896c63c"
|
||||
---
|
||||
|
||||
# NK-WP-0014 - User Engine Preparation And Boundary Contracts
|
||||
|
||||
## Goal
|
||||
|
||||
Prepare implementation of `/home/worsch/user-engine` by turning the current
|
||||
architecture review into concrete contracts. This workplan must be completed
|
||||
before production code is started, so the MVP does not duplicate IAM,
|
||||
authorization, application registration, membership, audit, or deployment
|
||||
responsibilities already owned by NetKingdom-aligned components.
|
||||
|
||||
## Context
|
||||
|
||||
The user-engine PRD and architecture blueprint define a headless user-domain
|
||||
service for users, accounts, profiles, preferences, memberships, application
|
||||
catalogs, projections, audit, and events.
|
||||
|
||||
The architecture review in
|
||||
`docs/reviews/2026-05-22T19-19-59+0200-user-engine-architecture-review.md`
|
||||
identified the main risk: duplicate truth across IAM providers, user-engine,
|
||||
flex-auth, application registrations, OIDC clients, protected systems, and
|
||||
profile projections.
|
||||
|
||||
NetKingdom keeps this workplan because it owns cross-repo boundary and
|
||||
orchestration guidance. Implementation work now lives in the `user-engine`
|
||||
repository as `USER-WP-0001` through `USER-WP-0006`.
|
||||
|
||||
## Scope
|
||||
|
||||
In scope:
|
||||
|
||||
- source-of-truth matrix;
|
||||
- membership synchronization contract;
|
||||
- application onboarding contract;
|
||||
- projection boundary split;
|
||||
- authorization performance model;
|
||||
- audit correlation contract;
|
||||
- user-engine repo preparation artifacts.
|
||||
- NetKingdom/user-engine interface guidance.
|
||||
|
||||
Out of scope:
|
||||
|
||||
- implementing user-engine production code, which belongs in the user-engine
|
||||
repository workplans;
|
||||
- implementing UI repos;
|
||||
- implementing SCIM or enterprise federation adapters;
|
||||
- changing the NetKingdom IAM Profile.
|
||||
|
||||
## Tasks
|
||||
|
||||
```task
|
||||
id: NK-WP-0014-T1
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "4e941174-ac55-4f6e-8568-40f45b1ed821"
|
||||
```
|
||||
|
||||
**Source-of-truth matrix.** Define which system owns each resource kind:
|
||||
identity claims, human subjects, local user records, account lifecycle,
|
||||
groups, roles, memberships, tenants, applications, OIDC clients,
|
||||
flex-auth protected systems, catalog namespaces, profile values,
|
||||
effective-profile projections, audit records, and events.
|
||||
|
||||
Initial guidance lives in `docs/user-engine-interface-guidance.md` and should
|
||||
be hardened into versioned contracts as implementation feedback arrives.
|
||||
|
||||
```task
|
||||
id: NK-WP-0014-T2
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "5ddc46bb-6238-4944-a023-d8b46b410c76"
|
||||
```
|
||||
|
||||
**Membership synchronization contract.** Specify which memberships are mastered
|
||||
in user-engine, which are imported from IAM or provisioning systems, which are
|
||||
exported to flex-auth, and how freshness, conflict handling, deletes, and
|
||||
tenant boundaries are represented.
|
||||
|
||||
```task
|
||||
id: NK-WP-0014-T3
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "696bc65b-0f8d-47b5-bccc-65ed285b42e6"
|
||||
```
|
||||
|
||||
**Application onboarding contract.** Define the binding between a user-engine
|
||||
application, IAM OIDC client, flex-auth protected system, catalog namespace,
|
||||
event/audit identity, and Railiance deployment metadata. Include a checklist
|
||||
for adding one new application safely.
|
||||
|
||||
```task
|
||||
id: NK-WP-0014-T4
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "99ab4535-cbbf-4e13-a2c5-adfc814d5aeb"
|
||||
```
|
||||
|
||||
**Projection and claims-enrichment boundaries.** Split projection types into
|
||||
runtime, self-service UI, admin UI, audit, agent context, and optional claims
|
||||
enrichment. Explicitly state that user-engine does not issue tokens and that
|
||||
claims enrichment is adapter-owned and cache/freshness governed.
|
||||
|
||||
```task
|
||||
id: NK-WP-0014-T5
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "d35a1356-a9fe-4cf3-8fb0-6f45cfbbccee"
|
||||
```
|
||||
|
||||
**Authorization and audit contracts.** Define the user-engine resource/action
|
||||
vocabulary for flex-auth, when checks are synchronous, when they may be
|
||||
batched or cached, and how user-engine audit records correlate with flex-auth
|
||||
decision IDs and platform audit sinks.
|
||||
|
||||
```task
|
||||
id: NK-WP-0014-T6
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "04fd2f92-3aa4-468d-9e9e-9b092890507e"
|
||||
```
|
||||
|
||||
**Prepare the user-engine repo.** Add or update user-engine `SCOPE.md`,
|
||||
architecture notes, repo layout decision, local development contract, and
|
||||
initial implementation readiness checklist. Do not add NetKingdom
|
||||
orchestration relationships to user-engine `INTENT.md`; those belong in
|
||||
NetKingdom documents per ADR-0010.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- Boundary contracts exist and are reviewed against the PRD and architecture
|
||||
review.
|
||||
- user-engine responsibilities are distinct from key-cape, Keycloak,
|
||||
flex-auth, OpenBao, Railiance, user-account, and user-manager.
|
||||
- The first implementation slice can start without unresolved ownership of
|
||||
memberships, applications, projections, authorization checks, or audit
|
||||
correlation.
|
||||
- user-engine repo-local workplans carry implementation tasks, while
|
||||
NetKingdom retains only boundary, orchestration, and responsibility-map work.
|
||||
- NetKingdom responsibility-map updates are either applied or explicitly
|
||||
deferred until user-engine becomes a shared platform service.
|
||||
|
||||
## Completion Notes
|
||||
|
||||
Completed on 2026-05-22:
|
||||
|
||||
- Added the canonical versioned contract at
|
||||
`canon/standards/user-engine-boundary-contract_v0.1.md`.
|
||||
- Promoted `docs/user-engine-interface-guidance.md` to an implementation guide
|
||||
that points at the canonical contract.
|
||||
- Confirmed `docs/responsibility-map.md` already includes `user-engine` as an
|
||||
orchestrated repository and names NetKingdom's boundary responsibilities.
|
||||
- Confirmed `/home/worsch/user-engine` already carries the required repo-local
|
||||
preparation artifacts: `SCOPE.md`, `wiki/ArchitectureBlueprint.md`,
|
||||
`docs/development.md`, `docs/configuration.md`,
|
||||
`docs/interfaces/netkingdom-integration.md`, and `USER-WP-0001` through
|
||||
`USER-WP-0006`.
|
||||
|
||||
## Dependencies And Sequencing
|
||||
|
||||
- Depends on NK-WP-0012 for IAM Profile consumption rules.
|
||||
- Depends on NK-WP-0013 for NetKingdom meta-orchestration conventions.
|
||||
- Gates implementation work in `/home/worsch/user-engine`, now tracked as
|
||||
`USER-WP-0001` through `USER-WP-0006`.
|
||||
Reference in New Issue
Block a user