From 7dafb6a3cf7a75518811178c691bfece3fc889e1 Mon Sep 17 00:00:00 2001 From: tegwick Date: Wed, 28 Oct 2026 00:06:55 +0100 Subject: [PATCH] NK-WP-0055-T13: production generate-root listener live; DR guide and crisis list updated Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 4515@bnt-lap001 Assistant-Session: 0bf96127-6e04-41be-bfda-d11717c3f354 --- docs/crisis-custody-list.md | 2 +- docs/disaster-recovery-storage-share.md | 9 +++++---- .../NK-WP-0055-security-platform-production-readiness.md | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/docs/crisis-custody-list.md b/docs/crisis-custody-list.md index 829db74..1dda6bb 100644 --- a/docs/crisis-custody-list.md +++ b/docs/crisis-custody-list.md @@ -32,7 +32,7 @@ circular dependency and is recorded as a gap, not as custody. | 1 | **`railiance-backup` age private key** (recipient `age1zvry…50syr3tsz`). Not the custodian key (item 1b) | Decrypts the identity backup bundle and the break-glass copy on Storage Share (`net-kingdom-kingpath-*.tar.age`) | Founder, password safe (stored as `railiance-backup.key`) | Yes, offline | Identity stages 2026-10-24; king-path verify drill 2026-10-27 (the helper refused the custodian key three times before the correct key was entered, as designed) | `TO CONFIRM`: number of copies, who else could recover if the founder cannot | | 1b | **Custodian age private key** (recipient `age1aq8t…qdepsh4`, `keys/age.pub` and `.sops.yaml`). Not the backup key | Decrypts the repository's SOPS custody files and greenfield bootstrap bundles (`docs/security-bootstrap-age-custody.md`) | Founder, password safe (stored as the custodian age private key) | Yes, offline | `TO CONFIRM` last proven use | Labels in the safe should name the recipient prefix so the two keys cannot be confused | | 2 | Storage Share `Backup` account app password | Downloads the protected ciphertext without OpenBao or SSO | Founder, independent custody `TO CONFIRM` | Yes, provider is outside the platform | Fresh retrieval 2026-10-24 | One provider copy only; residual risk accepted until 2027-01-31 (G1, NK-WP-0053) | -| 3 | OpenBao unseal shares (2 of 3 required in the restore drill) | Unseals a restored or production OpenBao; with the shares, `generate-root` can mint a root token for break-glass (ceremony not yet documented) | Founder as `platform-root` holds all three shares (single-holder custody: accepted exception, hub decision `37464824`, 2026-10-27), in the founder's replicated browser password safe under the `kingpath.credentials` pseudo-URL entry (confirmed 2026-10-27) | Yes: the safe is independent of NetKingdom SSO and OpenBao; it depends on the browser vendor's sync account and its own factor | Original shares used in the isolated restore RPF-WP-0064-T07, 2026-10-24 | Single holder = single point of loss (reviewed at NK-WP-0055-T09). The founder holds the initial root token offline (2026-10-27); its validity is checked in the king-path drill (NK-WP-0055-T13) against an isolated restored OpenBao, never production | +| 3 | OpenBao unseal shares (2 of 3 required in the restore drill) | Unseals a restored or production OpenBao; with the shares, `generate-root` mints a root token for break-glass (ceremony in `railiance-platform/docs/openbao.md`; production loopback listener 8210 live since 2026-10-28) | Founder as `platform-root` holds all three shares (single-holder custody: accepted exception, hub decision `37464824`, 2026-10-27), in the founder's replicated browser password safe under the `kingpath.credentials` pseudo-URL entry (confirmed 2026-10-27) | Yes: the safe is independent of NetKingdom SSO and OpenBao; it depends on the browser vendor's sync account and its own factor | Original shares used in the isolated restore RPF-WP-0064-T07, 2026-10-24 | Single holder = single point of loss (reviewed at NK-WP-0055-T09). The founder holds the initial root token offline (2026-10-27); its validity is checked in the king-path drill (NK-WP-0055-T13) against an isolated restored OpenBao, never production | | 4 | `platform-root` / king account and factors | Final authority; break-glass | Independently held password safe or offline packet (Standard §4; custody doc) | **No if used through KeyCape**: its login and OTP are validated by the services being recovered | OTP validated against restored privacyIDEA 2026-10-24 (isolated) | `TO CONFIRM` the offline path that works with SSO down (OpenBao shares, item 3) and record it | | 5 | Founder admission signing key (SSH, principal `bernd`) | Signs attempt and restore admissions | Founder, workstation key; verifier anchor `/etc/secrets-engine/admission/allowed_signers` | Yes | Signed the T40 admission 2026-10-23 | `TO CONFIRM` which identity this key belongs to; the anchor is workstation-bound, so a backup of key and anchor is needed | | 6 | `admin` password and OTP token | Day-to-day platform administration and, per intent, recovery operation | Founder; OTP enrolled 2026-10-24 | **No**: login and token checks need KeyCape, LLDAP and privacyIDEA | Token not yet in any restored backup; first restore proof after the 2026-10-25 03:45 UTC capture | Same account as the directory bind used by Authelia and privacyIDEA until the split in NK-WP-0054-T05 | diff --git a/docs/disaster-recovery-storage-share.md b/docs/disaster-recovery-storage-share.md index d0b86be..14b99d8 100644 --- a/docs/disaster-recovery-storage-share.md +++ b/docs/disaster-recovery-storage-share.md @@ -134,10 +134,11 @@ are signed by OpenBao. With those down, only paths built on offline material wor client certificate) through the `k3s-api-railiance01` tunnel, which uses a static SSH key. Today both are on the founder workstation only. - **OpenBao:** unseal with the shares (crisis list item 3). If an admin token is - needed while OIDC is down, the shares can mint a short-lived root token with - `generate-root`. **That ceremony is not documented yet**: - `railiance-platform/docs/openbao.md` covers only the initial root token. - Writing it down and drilling it is NK-WP-0055-T13. + needed while OIDC is down, the shares mint a short-lived root token with the + `generate-root` ceremony in `railiance-platform/docs/openbao.md` ("Break-glass: + OpenBao with SSO down"). On production it runs against the loopback-only + listener `127.0.0.1:8210`, reached with `kubectl port-forward` (live since + 2026-10-28, RAPP-OPENBAO-WP-0003). Revoke the token afterwards. - **Host:** console and rescue access through the Host Europe provider interface, which is independent of the platform. - **Workstation lost:** an age-encrypted copy of the cluster break-glass diff --git a/workplans/NK-WP-0055-security-platform-production-readiness.md b/workplans/NK-WP-0055-security-platform-production-readiness.md index 65d3f94..3157364 100644 --- a/workplans/NK-WP-0055-security-platform-production-readiness.md +++ b/workplans/NK-WP-0055-security-platform-production-readiness.md @@ -322,6 +322,8 @@ root token against an isolated restored OpenBao (never production); use produces 2026-10-27: `kingpath-offsite.py --verify UPLOAD_RECEIPT` added for the drill (7 more contained tests, 18 total): run under `sops-custody-unlock.sh --sealed-fd`, it checks the custody key against the recorded recipient, fetches the artifact with ETag/size/digest checks, refuses an unrelated key, decrypts in memory and checks each item's size and shape (kubeconfig with clusters/users, SSH private key header), writing a value-free receipt. The OpenBao part of the drill is RPF-WP-0064-T10 (drill mode being built). 2026-10-27 king-path drill, part 1 (founder-run): `kingpath-offsite.py --verify` restored `net-kingdom-kingpath-20261027T223050Z-8c9d48421f1b.tar.age` from Storage Share, refused an unrelated key, decrypted in memory and found `admin-kubeconfig` (kubeconfig shape) and `tunnel-ssh-key` (SSH private key header) intact. The custody helper refused the custodian age key three times before the founder entered the `railiance-backup` key; crisis list item 1 is split into 1 (backup key) and 1b (custodian key) so the two are not confused again. Part 2 (OpenBao, RPF-WP-0064-T10) is being built. + +2026-10-28: founder rolled out the loopback `generate-root` listener (RAPP-OPENBAO-WP-0003-T02): 200 on 8210 without a token, 405 on the main listener 8200. The break-glass ceremony can now run on production with SSO down. railiance-platform built and rehearsed the drill mode for part 2 (RPF-WP-0064-T10, `a2da408`: 34 offline tests, native rehearsal 16/16); its production read-only walk must be updated to expect 200 on 8210. ## Policy import pipeline and platform/tenant package split ```task