Files
net-kingdom/docs/openbao-unseal-custody-models.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

5.2 KiB
Raw Blame History

OpenBao Unseal Custody Models

Date: 2026-06-17 (updated 2026-07-02)
Status: all three models implemented — automation path proven greenfield; production models gated by deployment profile and evidence

NetKingdom bootstrap must support three OpenBao init/unseal custody models. Development starts with maximum automation for fast test cycles, then adds human custody gates as production trust increases.

This is separate from king custody mode (temporary-single-king, two-of-three-planned, two-of-three-ready) which governs who holds platform recovery authority. Unseal custody models govern how init/unseal executes during bootstrap and rebuild.


Models

Model ID Label Custody strength Automation Status
sops-held-automation SOPS-held unseal Lab / fast iteration High Implemented (console + creds agent path; greenfield-proven 2026-07-02)
attended-ceremony Attended ceremony Production Low Implemented (runbook + ceremony-record validator)
auto-unseal-transit Auto-unseal (transit/KMS) Production HA High Implemented (Helm seal stanza prepared; gate blocked until seal configured + verified)

sops-held-automation (default for greenfield dev)

  • Init/unseal material lives in SOPS/age custody bundle (not Git plaintext).
  • Applied by sso-mfa/bootstrap/openbao-init-unseal.sh (make openbao-init-unseal, NET-WP-0020 T2) after cluster + OpenBao pod exist. The helper enforces the console custody-model gate, initializes only when uninitialized (init JSON written straight into the age-custody secrets dir), replays unseal shares stdin-to-stdin, verifies post-unseal state, and emits non-secret openbao_initialized / openbao_post_unseal_verified evidence. Set OPENBAO_RUN_CONFIGURE_INITIAL=1 to chain railiance-platform: make openbao-configure-initial.
  • Enables unattended rebuild test cycles on a 3-node slate.
  • Not production trust posture — use to prove S1→S3→SSH engine automation, then graduate to stronger models.

attended-ceremony (production)

  • Human-attended bao operator init, out-of-band unseal share escrow, root token retirement — runbook: docs/openbao-attended-ceremony-runbook.md (command detail in railiance-platform/docs/openbao.md).
  • Matches first successful NetKingdom bootstrap (NET-WP-00150017).
  • Console keeps the refuse-live-init boundary; the ceremony is evidenced by a non-secret record validated with validate-openbao-ceremony-record (make security-bootstrap-validate-openbao-ceremony-record).

auto-unseal-transit (production HA)

  • OpenBao seal configuration uses transit or cloud KMS auto-unseal.
  • Pod restart without manual unseal threshold ceremony.
  • Seal stanza prepared (disabled by default) in railiance-platform/helm/openbao-values.yaml; enable + migrate per railiance-platform/docs/openbao.md "Auto-Unseal via Transit Seal".
  • Console init gate stays blocked until openbao_transit_seal_configured and openbao_auto_unseal_verified are set in the non-secret metadata.

Deployment profile

The console metadata carries a deployment_profile (lab default, production). The production profile blocks sops-held-automation — its SOPS bundle holds root token and unseal shares together, which is lab posture only. Selection, status gates, and openbao-init-unseal.sh all enforce the block:

make security-bootstrap-select-deployment-profile PROFILE=production

Each model is selectable in the security bootstrap console; gates express what evidence is still missing for the selected model.


Console integration

# List models and implementation status
python3 tools/security-bootstrap-console/security_bootstrap_console.py \
  openbao-unseal-custody-models

# Select active model (only implemented models succeed)
python3 tools/security-bootstrap-console/security_bootstrap_console.py \
  select-openbao-unseal-custody-model \
  --model sops-held-automation \
  --metadata .local/security-bootstrap.json

# Status shows gate: "OpenBao unseal custody model"
make security-bootstrap-console   # or: ... status --metadata .local/...

Metadata field: openbao_unseal_custody_model


Automation chain (after model selected)

Step Owner Target
S1 OS baseline railiance-infra 3 nodes
S2 k3s HA railiance-cluster ThreePhoenix
S3 OpenBao deploy railiance-platform make openbao-deploy
Init/unseal apply net-kingdom make openbao-init-unseal (sops-held)
Platform config railiance-platform openbao-configure-initial
SSH engine railiance-platform openbao-configure-ssh (planned)
Host CA trust railiance-infra bootstrap-ssh-ca (planned)
Sign smoke ops-warden warden sign (WP-0008 T2)

  • docs/smooth-bootstrap-guide.md — Step 5 (OpenBao init/unseal)
  • docs/platform-root-custody.md — king / quorum custody
  • railiance-platform/docs/openbao.md — deploy and ceremony
  • ops-warden/wiki/OpenBaoSshEngineChecklist.md — SSH engine verify
  • ops-warden/history/2026-06-17-openbao-production-verify.md — current blockers