--- id: NET-WP-0020 type: workplan title: "OpenBao Unseal Custody Models and SSH Automation Path" domain: infotech repo: net-kingdom status: active owner: codex topic_slug: net-kingdom created: "2026-06-17" updated: "2026-07-02" state_hub_workstream_id: "d6338ac9-797d-4009-8203-4b8dd39010af" --- # NET-WP-0020 — OpenBao Unseal Custody Models and SSH Automation Path **Scope:** Framework for three OpenBao init/unseal custody models; automation-first development path; console decision points; downstream hooks for SSH engine and host CA automation on greenfield 3-node bootstrap. **Strategy:** Start with `sops-held-automation` for fast unattended test cycles; add `attended-ceremony` and `auto-unseal-transit` with blocking gates as production trust increases. --- ## Tasks ### T1 — Custody model canon and console gates ```task id: NET-WP-0020-T01 status: done priority: high state_hub_task_id: "7040f347-d54a-42ba-a14f-5b0a7e691786" ``` - [x] `docs/openbao-unseal-custody-models.md` - [x] Console: list + select commands; gates block planned models - [x] `smooth-bootstrap-guide.md` Step 5 update - [x] Makefile targets ### T2 — SOPS-held init/unseal automation hooks ```task id: NET-WP-0020-T02 status: progress priority: high state_hub_task_id: "65407eb1-9d89-4158-aed5-4987badd83fc" ``` - [x] SOPS-held init/unseal automation: `sso-mfa/bootstrap/openbao-init-unseal.sh` (`make openbao-init-unseal` / `openbao-init-unseal-dry-run`) - [x] Non-secret evidence flags: `openbao_initialized`, `openbao_post_unseal_verified` (emitted on the script's `EVIDENCE` JSON line) - [x] Integrate with `make openbao-configure-initial` post-unseal (`OPENBAO_RUN_CONFIGURE_INITIAL=1` chains it; default prints the handoff hint) - [x] Wire the helper as an optional phase inside `creds-bootstrap-agent.sh` (Phase 7b, reviewed and approved by Bernd 2026-07-02: runs only when the `openbao` namespace exists, skips when already verified, sets the two `creds-state.yaml` flags, encrypts + commits new init material, and a custody-gate refusal warns without aborting the SSO/MFA bootstrap — dry-run/skip/refusal paths harness-tested) - [ ] Greenfield live proof: run against a sealed/uninitialized OpenBao on a rebuild slate (current cluster is already initialized+unsealed, so only the status/verify path was live-smoked on 2026-07-02; custody-gate refusal was proven for `unselected` and `attended-ceremony`) **2026-07-02 (later):** Bernd reviewed the helper design (five safety properties incl. the root-token-in-bundle caveat of the sops-held model) and approved the Phase 7b wiring as proposed. Applied, `bash -n` clean, all three conditional paths verified by harness. Pre-existing note: the agent's Phase 0 cannot dry-run on machines without the age key — unrelated to this change. Remaining T02 item is only the greenfield live proof. **2026-07-02:** Helper implemented and smoke-tested: dry-run against the live cluster passed the custody gate (`sops-held-automation` selected) and read `initialized=true sealed=false`; negative tests proved refusal for unselected and attended-ceremony models. Init material is written only into `secrets/openbao/` for age custody; unseal shares travel stdin-to-stdin and never appear in argv or logs. ### T3 — Attended ceremony automation profile ```task id: NET-WP-0020-T03 status: wait priority: medium state_hub_task_id: "34f3d979-a040-49ca-bfcb-35cf17473a06" ``` - [ ] Implement `attended-ceremony` selection path (runbooks + evidence validators) - [ ] Production profile blocks `sops-held-automation` default **Blocked until:** T2 automation path proven on greenfield rebuild. ### T4 — Auto-unseal transit profile ```task id: NET-WP-0020-T04 status: wait priority: medium state_hub_task_id: "54ab6505-c13b-4f63-8c94-07dd202de90a" ``` - [ ] `railiance-platform` Helm seal stanza for transit/KMS - [ ] Console gate + evidence for `auto-unseal-transit` ### T5 — SSH engine + host CA automation (cross-repo) ```task id: NET-WP-0020-T05 status: done priority: high state_hub_task_id: "399e82ca-6551-4020-8db5-c78076e75cfc" ``` - [x] `railiance-platform`: `openbao-configure-ssh` declarative script + Makefile targets - [x] `railiance-infra`: `bootstrap-ssh-ca` role + `ssh_principals.yaml` inventory - [x] Live apply: OpenBao SSH engine + roles + `warden-sign` on Railiance (2026-06-18) - [x] Live apply: `bootstrap-ssh-ca` on CoulombCore + Railiance01 - [x] Close `ops-warden` WP-0008 T2 verification gate --- ## See also - `history/2026-06-17-openbao-ssh-custody-and-bootstrap-assessment.md` — state + concepts (read before T5) - `ops-warden/workplans/WARDEN-WP-0008-production-ssh-path-and-stewardship-closeout.md` - `railiance-platform/docs/openbao.md`