This repository has been archived on 2026-07-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
net-kingdom/history/2026-07-02-openbao-greenfield-init-unseal-proof.md
tegwick 85a781b7a4 NET-WP-0020 finished: attended-ceremony + auto-unseal-transit profiles, greenfield init/unseal proof
T2: greenfield live proof against a fresh uninitialized OpenBao 2.5.5 —
caught and fixed 'bao operator unseal -' not reading stdin (now
'bao write sys/unseal key=-'); init and reseal-replay paths proven.
T3: attended-ceremony selectable — runbook, non-secret ceremony-record
template + validator, and a lab/production deployment profile that blocks
sops-held-automation in console selection, gates, and the init script.
T4: console gate + evidence flags for auto-unseal-transit (Helm seal stanza
prepared in railiance-platform).
Also: SCOPE.md refreshed to current repo state; adhoc fix for the broken
check-secrets Make target (unescaped $).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-02 22:08:33 +02:00

2.0 KiB

OpenBao greenfield init/unseal proof (NET-WP-0020 T2)

Date: 2026-07-02 Scope: sso-mfa/bootstrap/openbao-init-unseal.sh proven live against a genuinely uninitialized OpenBao 2.5.5 instance.

Method

A fresh local bao server (file storage, throwaway scratchpad dir) was started uninitialized and sealed. A kubectl shim forwarded the script's kubectl -n openbao exec openbao-0 -- bao … calls to the local instance, so the script ran byte-for-byte unmodified logic against real OpenBao. Console metadata lived in a scratch file with sops-held-automation selected.

This substitutes for the "rebuild slate" run: it exercises the exact init/unseal/verify code paths on a greenfield instance. The first 3-node rebuild will re-run the same script through creds-bootstrap-agent.sh Phase 7b.

Results

  1. Custody gate refusal — with no model selected, the script refused (unseal custody model is 'unselected'). Matches earlier negative tests.
  2. Bug found and fixedbao operator unseal - does not read the share from stdin (OpenBao treats - as the literal key: "'key' must be a valid hex or base64 string"; without an argument it demands a TTY). The live cluster never hit this because it was already unsealed. Fixed to bao write sys/unseal key=-, which reads the value from stdin — shares still never touch argv or logs.
  3. Greenfield init path — uninitialized → operator init (3 shares, threshold 2) → init.json written 0600 into the age-custody secrets dir → share replay stopped at threshold (share 2 of 3) → post-unseal verified. Evidence: openbao_did_init_this_run=true, openbao_initialized=true, openbao_post_unseal_verified=true.
  4. Restart/reseal path — server restarted (initialized + sealed) → script skipped init, replayed SOPS-held shares to threshold → verified. Evidence: openbao_did_init_this_run=false, both flags true.

Test server, storage, and init material were destroyed after the proof (init.json shredded).