NK-WP-0054: founder decision 9f0f7a87 - split goes live this week, admin dispositions, crisis list confirmed
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 308701@bnt-lap001 Assistant-Session: 5548e447-444c-4dcc-bed1-05c16eebfe56
This commit is contained in:
parent
417d88d80e
commit
dcb5bc2540
4 changed files with 36 additions and 12 deletions
|
|
@ -314,9 +314,9 @@
|
|||
| task | NK-WP-0054-T02 | done | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T03 | done | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T04 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T05 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T06 | wait | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T07 | todo | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T05 | progress | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T06 | done | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T07 | progress | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0054-T08 | done | — | workplans/NK-WP-0054-service-identity-policy.md |
|
||||
| task | NK-WP-0055-T01 | done | — | workplans/NK-WP-0055-security-platform-production-readiness.md |
|
||||
| task | NK-WP-0055-T02 | wait | — | workplans/NK-WP-0055-security-platform-production-readiness.md |
|
||||
|
|
|
|||
|
|
@ -116,6 +116,18 @@ The founder's model, written in canon terms. This is what the declarations must
|
|||
| provisioner account | `SERVICE` | `ADMINISTER @ directory/people,groups`, narrowest working scope | `STANDING` | `PRODUCTION` |
|
||||
| Claude Code, Codex, Grok sessions | `AGENT` | what the tools they can reach allow (SI-14) | per task | that of the person they act for |
|
||||
|
||||
Per-service admin disposition (founder decision `9f0f7a87`, 2026-10-28, NK-WP-0054-T06). A service with no
|
||||
local admin plane has no service-admin account; SI-4 applies where one exists.
|
||||
|
||||
| Service | Service-admin account | Custody | Day-to-day administration |
|
||||
| --- | --- | --- | --- |
|
||||
| LLDAP | `ld-admin`, configured super-admin (introduction rehearsed in isolation first) | Founder's password safe; crisis list | `admin` through an admin group |
|
||||
| privacyIDEA | `pi-admin` (exists; SI-X5) | Founder's replicated browser password safe; crisis item 7 | `pi-admin` until an attributed admin path exists |
|
||||
| Authelia | none: administered only through reviewed configuration | not applicable | reviewed config change |
|
||||
| KeyCape | none: client registry is configuration; `/platform/authentication-policy` needs role `platform-operator` at `aal2` | not applicable | `admin` with `platform-operator` |
|
||||
| OpenBao | none locally: federated `platform-admin` role (`aal2`); root only through the `generate-root` ceremony | unseal shares, crisis item 3 | `admin` via `platform-admin` |
|
||||
| PostgreSQL | CNPG `postgres` superuser | its cluster Secret, used only through railiance-platform | railiance-platform owner operations |
|
||||
|
||||
`backup operator → OPERATE @ backup-system` and `developer → CONSTRUCT @ product` are the canon's own
|
||||
translations, and match the founder's intent that `admin` operates backups and `tegwick` builds.
|
||||
|
||||
|
|
|
|||
|
|
@ -29,9 +29,9 @@ circular dependency and is recorded as a gap, not as custody.
|
|||
|
||||
| # | Item | Unlocks | Holder and location | Works with SSO and OpenBao down? | Last proven use | Gap or action |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| 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) |
|
||||
| 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`) | Two copies: founder's password safe (stored as `railiance-backup.key`) and a copy held by a named trusted person, who can recover if the founder cannot (founder, 2026-10-28) | 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) | Successor copy is not drill-proven; prove it once with `kingpath-offsite.py --verify` run by or with the successor |
|
||||
| 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 | 2026-10, bootstrap/SOPS work (founder, 2026-10-28; not yet receipt-proven: run `make sops-custody-check`) | 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, in the independent password safe (founder, 2026-10-28) | 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` 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; the king-path drill (2026-10-28) found it **valid** as of the 2026-10-14 snapshot (root policy, no TTL, orphan). Founder decision `7ce684ec` (2026-10-28): stays escrowed during builder mode, revoked at production entry (NK-WP-0055-T16) |
|
||||
| 4 | `platform-root` / king account and factors | Final authority; break-glass | Independently held password safe (kingpath entry) | **No if used through KeyCape**. The king path with SSO down is offline material instead: unseal shares (item 3) plus the `generate-root` ceremony on the loopback listener, the admin kubeconfig and static tunnel key (item 9, also on Storage Share), the Host Europe console, and the admission signing key (item 5) | OTP validated against restored privacyIDEA 2026-10-24 (isolated). King path drilled 2026-10-28: Storage Share restore of item 9, `generate-root` on an isolated restore, read-only production SSO-down walk ([record](evidence/2026-10-28-king-path-drill.md)) | Not drilled: using the restored item-9 material against the cluster, and the Host Europe console. Both belong in the recurring drill (NK-WP-0053) |
|
||||
| 5 | Founder admission signing key (SSH ed25519, principal `bernd`, fingerprint `SHA256:NekDABfw8K8IBYznjREg7jPpcK/BzCgO1pH1ebT/FXM`) | Signs restore and drill admissions for the OpenBao isolated restore (namespace `railiance-openbao-restore-attempt`) and secrets-engine admissions | Private key: founder workstation `~/.ssh/gexec_approver_ed25519` (passphrase-protected; signed the T40, `-02` and `-03` admissions); founder decision 2026-10-28: also keep it in the password safe under the kingpath entry, **not** in the Storage Share bundle, so the backup age key alone cannot admit a restore. Public anchor (non-secret, needed on any recovery workstation): `/etc/railiance-openbao-restore/allowed_signers` and `/etc/secrets-engine/admission/allowed_signers`, one line each: `bernd namespaces="railiance-openbao-restore-attempt" ssh-ed25519 ssh-ed25519` ; the secrets-engine file uses namespace `secrets-engine-recovery-attempt` | Yes, offline | Signed the T40 admission 2026-10-23 | Private key stored in the password safe kingpath entry (founder, 2026-10-28). Re-create both anchor files from this row on a recovery workstation. The file name says `gexec_approver`, but the key's role is admission signing |
|
||||
|
|
|
|||
|
|
@ -229,13 +229,12 @@ The founder's live export commands are in RPF-WP-0067-T03.
|
|||
|
||||
```task
|
||||
id: NK-WP-0054-T05
|
||||
status: wait
|
||||
status: progress
|
||||
priority: high
|
||||
assignee: claude-code
|
||||
needs_human: true
|
||||
decision_id: "9f0f7a87-7adb-44f6-8360-db6a80e3ceca"
|
||||
depends_on: [NK-WP-0054-T01]
|
||||
blocking_reason: "Production change across LLDAP, Authelia, privacyIDEA and their Secrets; needs the founder's go and the platform owners. The founder runs live Secret and rollout steps."
|
||||
state_hub_task_id: "c43d339a-fc8a-5526-885a-64693c930005"
|
||||
```
|
||||
|
||||
|
|
@ -258,17 +257,24 @@ filled-in commands; the founder runs the live steps.
|
|||
password is not present in any service Secret, a fresh backup restores and passes the T17
|
||||
and T19 drills under the new accounts, and the old shared credential is retired.
|
||||
|
||||
**2026-10-28 founder decision `9f0f7a87`: go, including the live run this week.** Order: guarded
|
||||
helpers and filled-in commands; an isolated rehearsal on a restored copy of the directory covering
|
||||
the `ld-admin` introduction, demotion of `admin` to an admin group, the narrowest provisioner
|
||||
privilege on the pinned LLDAP image, and SI-3 (can a `svc-*` bind be kept from interactive login);
|
||||
then the founder runs the live steps as soon as the rehearsal passes. KeyCape's bind is confirmed
|
||||
as the directory admin from source (key-cape `a1ab8ff`, KEY-WP-0045-T03). The rotation lane is
|
||||
`lldap-directory-bind` / `lldap-service-binds` in `tools/rotation-lanes/lanes.yaml`.
|
||||
|
||||
## Disposition of per-service admin accounts
|
||||
|
||||
```task
|
||||
id: NK-WP-0054-T06
|
||||
status: wait
|
||||
status: done
|
||||
priority: medium
|
||||
assignee: claude-code
|
||||
needs_human: true
|
||||
decision_id: "9f0f7a87-7adb-44f6-8360-db6a80e3ceca"
|
||||
depends_on: [NK-WP-0054-T02]
|
||||
blocking_reason: "Founder decision per service: which dedicated admin account exists, its name and its custody."
|
||||
state_hub_task_id: "8072b5cf-4161-58b9-8dfc-62fa102ccd16"
|
||||
```
|
||||
|
||||
|
|
@ -281,16 +287,22 @@ whether a read-only bind account can be kept from signing in interactively (SI-3
|
|||
|
||||
**Done when:** every service has a recorded disposition and a custody location.
|
||||
|
||||
**Done 2026-10-28, founder decision `9f0f7a87`:** dispositions accepted as proposed and recorded in
|
||||
the standard (section "Per-service admin disposition"): LLDAP `ld-admin`; privacyIDEA `pi-admin`;
|
||||
Authelia and KeyCape none (configuration-only, no local admin plane); OpenBao federated
|
||||
`platform-admin` with root only via `generate-root`; PostgreSQL the CNPG `postgres` superuser through
|
||||
railiance-platform. The `ld-admin` introduction and the SI-3 check are rehearsed under T05.
|
||||
|
||||
## Maintain the crisis custody list
|
||||
|
||||
```task
|
||||
id: NK-WP-0054-T07
|
||||
status: todo
|
||||
status: progress
|
||||
priority: high
|
||||
assignee: claude-code
|
||||
needs_human: true
|
||||
decision_id: "9f0f7a87-7adb-44f6-8360-db6a80e3ceca"
|
||||
blocking_reason: "The founder confirms every TO CONFIRM row in docs/crisis-custody-list.md: share holders, copies of the age key, the crisis path to production, bundle location."
|
||||
blocking_reason: "No TO CONFIRM row remains (2026-10-28). Open: the machine-readable freshness check and the first admin-operated drill (NK-WP-0053) verifying the list."
|
||||
state_hub_task_id: "ae8524ff-12d8-59c2-b46b-88f3bfd44dd8"
|
||||
```
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue