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>
5.2 KiB
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-secretopenbao_initialized/openbao_post_unseal_verifiedevidence. SetOPENBAO_RUN_CONFIGURE_INITIAL=1to chainrailiance-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 inrailiance-platform/docs/openbao.md). - Matches first successful NetKingdom bootstrap (NET-WP-0015–0017).
- 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 perrailiance-platform/docs/openbao.md"Auto-Unseal via Transit Seal". - Console init gate stays blocked until
openbao_transit_seal_configuredandopenbao_auto_unseal_verifiedare 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) |
Related docs
docs/smooth-bootstrap-guide.md— Step 5 (OpenBao init/unseal)docs/platform-root-custody.md— king / quorum custodyrailiance-platform/docs/openbao.md— deploy and ceremonyops-warden/wiki/OpenBaoSshEngineChecklist.md— SSH engine verifyops-warden/history/2026-06-17-openbao-production-verify.md— current blockers