generated from coulomb/repo-seed
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>
This commit is contained in:
82
docs/openbao-attended-ceremony-runbook.md
Normal file
82
docs/openbao-attended-ceremony-runbook.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# OpenBao Attended Ceremony Runbook
|
||||
|
||||
Date: 2026-07-02
|
||||
Status: active — production custody model (`attended-ceremony`, NET-WP-0020 T3)
|
||||
|
||||
Human-attended OpenBao init/unseal for production trust posture. The security
|
||||
bootstrap console **never runs `bao operator init`** (refuse-live-init
|
||||
boundary) — this runbook is executed by the `openbao-ceremony-operator` role
|
||||
and evidenced by a **non-secret** ceremony record.
|
||||
|
||||
Contrast with `sops-held-automation` (lab posture): there, root token and
|
||||
unseal shares live together in one SOPS bundle for unattended rebuild loops.
|
||||
The attended ceremony keeps unseal shares **out of band** and retires the root
|
||||
token, so no single artifact can open the platform.
|
||||
|
||||
---
|
||||
|
||||
## Preconditions
|
||||
|
||||
1. Console gates green up to the init ceremony:
|
||||
`make security-bootstrap-console` — custody strategy approved, preflight
|
||||
passed.
|
||||
2. Select profile and model (production blocks the lab default):
|
||||
|
||||
```bash
|
||||
python3 tools/security-bootstrap-console/security_bootstrap_console.py \
|
||||
--metadata .local/security-bootstrap.json \
|
||||
select-deployment-profile --profile production
|
||||
|
||||
python3 tools/security-bootstrap-console/security_bootstrap_console.py \
|
||||
--metadata .local/security-bootstrap.json \
|
||||
select-openbao-unseal-custody-model --model attended-ceremony
|
||||
```
|
||||
|
||||
3. OpenBao deployed and reachable:
|
||||
`make -C ../railiance-platform openbao-status` (expect uninitialized/sealed
|
||||
on greenfield).
|
||||
4. Two people present (operator + witness) where the custody roster requires
|
||||
it; unseal-share escrow destinations agreed per
|
||||
`docs/platform-root-custody.md` (signed custody roster).
|
||||
|
||||
## Ceremony
|
||||
|
||||
Follow `railiance-platform/docs/openbao.md` for the exact commands. Outline:
|
||||
|
||||
1. **Init** — operator runs `bao operator init` (3 shares, threshold 2)
|
||||
directly against the pod from a terminal. Output goes only to the
|
||||
operator's screen — never into the console, chat, State Hub, or files
|
||||
inside a Git checkout.
|
||||
2. **Escrow** — each unseal share is transcribed to its escrow destination
|
||||
(offline packet / password safe per roster). No two shares in the same
|
||||
custody location.
|
||||
3. **Unseal** — replay threshold shares; verify
|
||||
`initialized=true sealed=false`.
|
||||
4. **Root retirement** — use the root token only for the initial
|
||||
configuration handoff (`make -C ../railiance-platform
|
||||
openbao-configure-initial`), then revoke it (`bao token revoke -self`) or
|
||||
escrow it per roster; record the disposition.
|
||||
|
||||
## Evidence
|
||||
|
||||
Record the ceremony in a non-secret JSON record and validate it:
|
||||
|
||||
```bash
|
||||
python3 tools/security-bootstrap-console/security_bootstrap_console.py \
|
||||
openbao-ceremony-record-template > .local/openbao-ceremony-record.json
|
||||
# edit: dispositions, dates, roles — NEVER shares, tokens, or key material
|
||||
|
||||
make security-bootstrap-validate-openbao-ceremony-record
|
||||
```
|
||||
|
||||
The validator refuses records containing secret-looking markers (tokens, key
|
||||
blocks, otpauth URIs) or leftover template placeholders. After a valid
|
||||
record, set the console flags (`openbao_initialized`,
|
||||
`openbao_post_unseal_verified`) in the metadata so the gates advance.
|
||||
|
||||
## Related
|
||||
|
||||
- `docs/openbao-unseal-custody-models.md` — model framework
|
||||
- `docs/platform-root-custody.md` — custody roster and share holders
|
||||
- `docs/security-bootstrap-openbao-ceremony-ux.md` — operator UX notes
|
||||
- `railiance-platform/docs/openbao.md` — deploy + command-level ceremony
|
||||
@@ -1,7 +1,8 @@
|
||||
# OpenBao Unseal Custody Models
|
||||
|
||||
Date: 2026-06-17
|
||||
Status: framework — automation path active; production paths planned
|
||||
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
|
||||
@@ -18,9 +19,9 @@ during bootstrap and rebuild.
|
||||
|
||||
| Model ID | Label | Custody strength | Automation | Status |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `sops-held-automation` | SOPS-held unseal | Lab / fast iteration | High | **Implemented** (console + creds agent path) |
|
||||
| `attended-ceremony` | Attended ceremony | Production | Low | Planned |
|
||||
| `auto-unseal-transit` | Auto-unseal (transit/KMS) | Production HA | High | Planned |
|
||||
| `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)
|
||||
|
||||
@@ -37,32 +38,42 @@ during bootstrap and rebuild.
|
||||
- **Not** production trust posture — use to prove S1→S3→SSH engine automation,
|
||||
then graduate to stronger models.
|
||||
|
||||
### `attended-ceremony` (production target)
|
||||
### `attended-ceremony` (production)
|
||||
|
||||
- Human-attended `bao operator init`, out-of-band unseal share escrow, root token
|
||||
retirement — per `railiance-platform/docs/openbao.md`.
|
||||
retirement — runbook: `docs/openbao-attended-ceremony-runbook.md`
|
||||
(command detail in `railiance-platform/docs/openbao.md`).
|
||||
- Matches first successful NetKingdom bootstrap (NET-WP-0015–0017).
|
||||
- Console keeps **refuse-live-init** boundary; ceremony runbooks only.
|
||||
- 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 target)
|
||||
### `auto-unseal-transit` (production HA)
|
||||
|
||||
- OpenBao seal configuration uses **transit** or cloud KMS auto-unseal.
|
||||
- Pod restart without manual unseal threshold ceremony.
|
||||
- Requires `railiance-platform` Helm seal stanza + KMS provisioning.
|
||||
- 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.
|
||||
|
||||
---
|
||||
|
||||
## Development strategy
|
||||
## Deployment profile
|
||||
|
||||
```text
|
||||
1. Implement automation path (sops-held-automation)
|
||||
→ SSH engine, warden sign, host CA trust, 3-node rebuild loops
|
||||
2. Add attended-ceremony gates (block automation defaults in production profile)
|
||||
3. Add auto-unseal-transit for HA ThreePhoenix rebuilds
|
||||
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:
|
||||
|
||||
```bash
|
||||
make security-bootstrap-select-deployment-profile PROFILE=production
|
||||
```
|
||||
|
||||
Each model is selectable in the **security bootstrap console**. Unimplemented
|
||||
models are **blocked** with a hint pointing to the active automation path.
|
||||
Each model is selectable in the **security bootstrap console**; gates express
|
||||
what evidence is still missing for the selected model.
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user