diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index ea4cbd2..e8c381f 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -44,7 +44,6 @@ | workplan | RPF-WP-0061 | active | — | workplans/RPF-WP-0061-self-service-ccr-intake.md | | workplan | RPF-WP-0062 | finished | — | workplans/RPF-WP-0062-custodian-agent-observer-identity.md | | workplan | RPF-WP-0063 | finished | — | workplans/RPF-WP-0063-wave2-resource-right-sizing.md | -| workplan | RPF-WP-0064 | active | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | | workplan | RPF-WP-0065 | proposed | — | workplans/RPF-WP-0065-netkingdom-role-claim-bindings.md | | workplan | RPF-WP-0066 | proposed | — | workplans/RPF-WP-0066-openbao-durable-audit-snapshots-conformance.md | | workplan | RPF-WP-0067 | finished | — | workplans/RPF-WP-0067-netkingdom-identity-receipt-and-metadata-answers.md | @@ -53,6 +52,7 @@ | workplan | RPF-WP-0070 | finished | — | workplans/RPF-WP-0070-mas-evidence-recovery.md | | workplan | RPF-WP-0071 | backlog | — | workplans/RPF-WP-0071-attended-credential-rotation-lane.md | | workplan | RPF-WP-0072 | backlog | — | workplans/RPF-WP-0072-audit-core-recovery-compatibility.md | +| workplan | RPF-WP-0073 | backlog | — | workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md | | task | RPF-WP-ADHOC-2026-10-10-T01 | done | — | workplans/ADHOC-2026-10-10.md | | task | RPF-WP-ADHOC-2026-10-11-T01 | done | — | workplans/ADHOC-2026-10-11.md | | task | RPF-WP-ADHOC-2026-10-11-T02 | done | — | workplans/ADHOC-2026-10-11.md | @@ -208,16 +208,6 @@ | task | RPF-WP-0062-T02 | done | — | workplans/RPF-WP-0062-custodian-agent-observer-identity.md | | task | RPF-WP-0062-T03 | done | — | workplans/RPF-WP-0062-custodian-agent-observer-identity.md | | task | RPF-WP-0063-T01 | done | — | workplans/RPF-WP-0063-wave2-resource-right-sizing.md | -| task | RPF-WP-0064-T01 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T02 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T03 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T04 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T05 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T06 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T07 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T08 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T09 | wait | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | -| task | RPF-WP-0064-T10 | done | — | workplans/RPF-WP-0064-isolated-original-openbao-restore.md | | task | RPF-WP-0065-T01 | done | — | workplans/RPF-WP-0065-netkingdom-role-claim-bindings.md | | task | RPF-WP-0065-T02 | done | — | workplans/RPF-WP-0065-netkingdom-role-claim-bindings.md | | task | RPF-WP-0065-T03 | done | — | workplans/RPF-WP-0065-netkingdom-role-claim-bindings.md | @@ -253,6 +243,8 @@ | task | RPF-WP-0071-T01 | todo | — | workplans/RPF-WP-0071-attended-credential-rotation-lane.md | | task | RPF-WP-0071-T02 | todo | — | workplans/RPF-WP-0071-attended-credential-rotation-lane.md | | task | RPF-WP-0072-T01 | todo | — | workplans/RPF-WP-0072-audit-core-recovery-compatibility.md | +| task | RPF-WP-0073-T01 | wait | — | workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md | +| task | RPF-WP-0073-T02 | wait | — | workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md | | intake | RPF-IN-0001 | closed | — | intakes/intakes.md | | intake | RPF-IN-0002 | open | — | intakes/intakes.md | | intake | RPF-IN-0003 | open | — | intakes/intakes.md | diff --git a/docs/openbao-isolated-restore.md b/docs/openbao-isolated-restore.md index 85b3473..15875ca 100644 --- a/docs/openbao-isolated-restore.md +++ b/docs/openbao-isolated-restore.md @@ -1,7 +1,7 @@ # Isolated original-OpenBao restore (RPF-WP-0064) Adapter: `scripts/openbao-isolated-restore/`. Workplan: -`workplans/RPF-WP-0064-isolated-original-openbao-restore.md`. +`workplans/archived/261104-RPF-WP-0064-isolated-original-openbao-restore.md` (phase B: `workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md`). This restores the original OpenBao Raft snapshot into a disposable, networkless container on the founder workstation. It unseals the snapshot with diff --git a/workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md b/workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md new file mode 100644 index 0000000..6682ae2 --- /dev/null +++ b/workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md @@ -0,0 +1,134 @@ +--- +id: RPF-WP-0073 +type: workplan +title: "Phase B: isolated original-OpenBao restore on a contained network for the NK-WP-0049-T44 drill" +domain: financials +repo: railiance-platform +status: backlog +flavor: implementation +owner: claude +created: "2026-11-04" +updated: "2026-11-04" +related: + - RPF-WP-0064 + - NK-WP-0049 + - SECRETS-WP-0015 +--- + +# RPF-WP-0073 — Phase B restore for the NK-WP-0049-T44 pre-production drill + +Successor to RPF-WP-0064, which finished phase A on 2026-11-04: the original OpenBao was +restored in isolation and independently verified (receipt `4e048dee…579d`), and the break-glass +drill ran. Phase B keeps the restored original OpenBao up on one contained `--internal` network, +so the isolated KeyCape and the secrets-engine consumer can do a live JWT login against it. + +**Parked.** On 2026-10-27 the founder chose option A (builder mode) for NK-WP-0049. Phase B was +paused, not cancelled. The joint live consumer login moved to net-kingdom's pre-production drill +NK-WP-0049-T44, which reuses the design below (inherited-pipe runner, the agreed network names). +NetKingdom asked that these items stay parked against T44 (hub message `cfffcd7b`). Nothing here +starts until T44 is scheduled. + +Context that stays in the archived predecessor +(`workplans/archived/261104-RPF-WP-0064-isolated-original-openbao-restore.md`): +- the phase A adapter, receipt and verifier; +- the agreed phase B network, subnet and container names ("Owner answers to NK-WP-0049-T43", + item 2); +- residuals R1–R8. R1 (unproven extra JWT config fields) and R2 (no live JWT login) close here. + +Settled since: NetKingdom reports that the pinned image `436eaf97` trusts the exact ISRG Root X1 +anchor of the KeyCape chain. That covers item 8's trust question; the readback still needs a +presence-only check of the four CA and discovery fields (R1). + +### Phase B design carried over from RPF-WP-0064 (2026-10-27, reply to net-kingdom message 5da58a3d) + +Source: net-kingdom `docs/nk49-phase-b-plan.md` (NK-WP-0049-T43); founder decision of 2026-10-27 names +railiance-platform as creator and tearer-down of the single `--internal` network and as keeper of the restored +OpenBao for the admitted window. **Preparation only.** This confirmation authorizes nothing, starts nothing and +creates no network. Every start needs a new founder-signed window; the `-03` admission (`3ef17fd1…4cc9`) and the +T40 window carry nothing over. + +**Confirmed:** railiance-platform can own (a) network create/inspect/egress-refusal proof/removal, and (b) the +phase A restore followed by keeping OpenBao up unsealed on that network for the admitted window, with a phase B +receipt. Subject to the changes and reviews below. + +**What the adapter does today (`7084b57`, attempt -03):** `--network none`, `lo` only, listener +`127.0.0.1:8200` with `tls_disable`, `api_addr`/`cluster_addr` on loopback, generate-root enabled +unauthenticated on that loopback listener, `check_network` requires `none`, receipt schema lists +`phase_b_network` as a not-claimed field, the verifier rejects phase B, teardown always runs (or by reaper), 45 +minute deadline from first custody input, no volumes. + +**What must change (new mode, phase A path stays byte-identical in behaviour):** +1. Admission and preflight: new signed phase B admission naming the network name, subnet, OpenBao alias + (`bao-restored`), admitted container set, window and adapter commit; preflight refuses a pre-existing + network or stale `rpf64-*` objects. +2. Network lifecycle: create `docker network create --internal` with a label naming the attempt; prove + `Internal=true`, no gateway, empty attached set; prove egress refused (public address, non-admitted name) + from a probe container before admission continues; at the end remove the network last and show it gone. The + reaper removes only objects carrying this attempt's label, never a network it did not create. +3. Listener: OpenBao must listen on the internal address (`0.0.0.0` inside the namespace, reachable only via the + internal network), `api_addr` accordingly, `--network --network-alias bao-restored`. Raft + `cluster_addr` stays loopback (single node). +4. `check_network` variant: exactly one named internal network, inspected `Internal=true`, attached set equals + the admitted containers, subnet route and no default route; the `lo`-only check is replaced for this mode. +5. Readback credential: phase A uses generate-root from the entered shares. In phase B the + unauthenticated-generate-root setting must **not** be exposed on the internal listener. Plan: keep it on a + separate loopback-only listener used for readback, or disable it after readback; the credential is revoked and + shown dead before the consumer is admitted to the network. The consumer only ever uses the JWT role. +6. Lifetime: do not tear down after readback; stay up until the founder window ends, a consumer-done signal, or + abort. The 45 minute limit runs from first custody input, so OpenBao starts last among long-lived pieces + (as the plan orders), and the consumer run follows at once. Hard deadline plus reaper stay. +7. Receipt schema v-next, verifier and adversarial fixtures for the phase B receipt (network facts, egress + refusal, revocation before consumer admission, teardown including network removal); no secret values, no KV + data. `phase_b_network` moves from not-claimed to claimed only in that mode. +8. TLS trust (net-kingdom item 4): OpenBao must trust the ISRG Root X1 chain to fetch + `https://kc.coulomb.social/jwks`; verify in the native rehearsal whether the pinned image's CA bundle suffices + and do not assume it. No self-signed substitute and no injected trust file without owner review. +9. Rehearsal: native run with synthetic material on a throwaway internal network plus a stand-in JWKS server; + offline tests extended. + +**Needs review:** all of the above is a new adapter commit and a new pin (T06 owner confirmation); the listener +and generate-root change (item 5) is the security-sensitive point and wants the same review depth as the phase A +adapter; admission schema change; independent verification of the phase B receipt from a clean clone. Network +subnet and container naming must be agreed with net-kingdom so the attached-set check matches. + +**Objections / conditions:** +- OpenBao stays up with an unsealed backend reachable by the consumer for hours versus the 45 minute phase A + bound; the founder must accept the longer exposure explicitly in the window (24 h maximum proposed; I suggest + a much shorter window). +- Ordering: network exists before the isolated KeyCape starts; whichever party starts second must not alter the + attached set. If NetKingdom's KeyCape cannot attach to a pre-created network, the plan fails closed. +- Docker is the only supported runtime here; the consumer runner is attached by the consumer owner and checked + by me by inspection only. +- No live action, no network creation, no custody input until the window, the new admission and pin exist. + +## Phase B source preparation (from RPF-WP-0064-T09) + +```task +id: RPF-WP-0073-T01 +status: wait +priority: medium +blocked_on: dependency +blocking_reason: "Parked against net-kingdom NK-WP-0049-T44 (pre-production drill) by founder decision 2026-10-27 (hub message cfffcd7b); resume when T44 is scheduled" +``` + +Implement items 1–9 above as a separate adapter mode; the phase A path keeps its behaviour. Then +rehearse natively with synthetic material, get owner review and a new pin (T06-style), and wait for a +new founder-signed phase B window. No live run is part of this task. + +## Attended phase B window + +```task +id: RPF-WP-0073-T02 +status: wait +priority: medium +needs_human: true +depends_on: [RPF-WP-0073-T01] +blocked_on: dependency +blocking_reason: "Needs T01, NK-WP-0049-T44 scheduling and a new founder-signed phase B admission" +``` + +Run the admitted phase B mode once in the T44 drill window. Produce a phase B receipt that a clean +clone verifies independently: network facts, egress refusal, readback revoked before the consumer is +admitted, and teardown including network removal. Hand the receipt to net-kingdom (T44) and +secrets-engine (SECRETS-WP-0015-T04). Make no claim of consumer continuity beyond what the receipt +shows. diff --git a/workplans/RPF-WP-0064-isolated-original-openbao-restore.md b/workplans/archived/261104-RPF-WP-0064-isolated-original-openbao-restore.md similarity index 99% rename from workplans/RPF-WP-0064-isolated-original-openbao-restore.md rename to workplans/archived/261104-RPF-WP-0064-isolated-original-openbao-restore.md index 696a7b6..afa169a 100644 --- a/workplans/RPF-WP-0064-isolated-original-openbao-restore.md +++ b/workplans/archived/261104-RPF-WP-0064-isolated-original-openbao-restore.md @@ -4,7 +4,7 @@ type: workplan title: "Isolated original-OpenBao restore for secrets-engine consumer continuity" domain: financials repo: railiance-platform -status: active +status: finished flavor: implementation owner: claude created: "2026-10-23" @@ -21,6 +21,9 @@ state_hub_workstream_id: "e19808db-52d6-508b-b70c-6775c4f78c4f" # RPF-WP-0064 — Isolated original-OpenBao restore for secrets-engine consumer continuity +**Finished 2026-11-04.** Phase A restored the original and was independently verified (T07). The +break-glass drill is done (T10). Phase B moved to RPF-WP-0073, parked against NK-WP-0049-T44. + Receiving workplan for hub message `41e9af3e` from net-kingdom (case `secrets15-nk49-readiness`). The founder accepted on 2026-10-23 that railiance-platform owns this as source preparation. @@ -505,11 +508,9 @@ subnet and container naming must be agreed with net-kingdom so the attached-set ```task id: RPF-WP-0064-T09 -status: wait +status: cancel priority: medium depends_on: [RPF-WP-0064-T08] -blocked_on: dependency -blocking_reason: "Parked against net-kingdom NK-WP-0049-T44 (pre-production drill) by founder decision 2026-10-27 (net-kingdom hub message cfffcd7b): no build or run needed now" state_hub_task_id: "ef4ded2e-af0c-5e3f-8b8c-aad80e8be074" ``` @@ -524,6 +525,9 @@ which reuses the accepted design (inherited-pipe runner, the phase B network nam NetKingdom asked that these items stay parked against T44 (hub message `cfffcd7b`). Resume only when T44 is scheduled. +2026-11-04: moved to **RPF-WP-0073** (T01 preparation, T02 attended window), and this plan is +closed. Cancelled here, not done. + The same message reports on item 8: the pinned OpenBao image `436eaf97` trusts the exact ISRG Root X1 anchor of the KeyCape chain. This is NetKingdom's check, not repeated here. Residual R1 (presence-only check of the CA fields in the readback) stays a phase B item.