generated from coulomb/repo-seed
NET-WP-0020-T02: wire OpenBao init/unseal as Phase 7b in creds-bootstrap-agent (operator-reviewed)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -298,6 +298,45 @@ else
|
||||
echo " [dry-run] would run: bash creds-verify.sh"
|
||||
fi
|
||||
|
||||
# ── Phase 7b: OpenBao init/unseal (sops-held-automation, optional) ───────────
|
||||
|
||||
step "7b — OpenBao init/unseal (sops-held-automation, optional)"
|
||||
|
||||
# NET-WP-0020 T2: greenfield-rebuild hook. Runs only when the openbao
|
||||
# namespace exists AND the console has selected sops-held-automation
|
||||
# (the helper enforces that gate itself and refuses attended-ceremony /
|
||||
# auto-unseal-transit). Skipped silently on clusters without OpenBao.
|
||||
if kubectl get namespace openbao &>/dev/null; then
|
||||
if [[ "$(state_get openbao_post_unseal_verified)" == "true" ]]; then
|
||||
ok "OpenBao already verified — skipping"
|
||||
elif [[ "$DRY_RUN" == false ]]; then
|
||||
if (cd "$SCRIPT_DIR" && bash openbao-init-unseal.sh "$SECRETS_DIR"); then
|
||||
state_set "openbao_initialized" "true"
|
||||
state_set "openbao_post_unseal_verified" "true"
|
||||
ok "OpenBao initialized/unsealed and verified"
|
||||
|
||||
# New init material must reach age custody before cleanup.
|
||||
if [[ -d "$SECRETS_DIR/openbao" ]]; then
|
||||
log "encrypting OpenBao init material → secrets.enc/ ..."
|
||||
(cd "$SCRIPT_DIR" && bash encrypt-secrets.sh \
|
||||
"$SECRETS_DIR" "$AGE_KEY" --no-shred)
|
||||
cd "$REPO_ROOT"
|
||||
git add sso-mfa/bootstrap/secrets.enc/ \
|
||||
sso-mfa/bootstrap/creds-state.yaml
|
||||
git diff --cached --quiet || git commit -m \
|
||||
"chore(creds): encrypted OpenBao init material [agent]"
|
||||
fi
|
||||
else
|
||||
warn "OpenBao init/unseal did not complete — see output"
|
||||
warn "(gate unselected or pod not ready; bootstrap continues)"
|
||||
fi
|
||||
else
|
||||
echo " [dry-run] would run: openbao-init-unseal.sh $SECRETS_DIR"
|
||||
fi
|
||||
else
|
||||
ok "no openbao namespace in this cluster — skipping"
|
||||
fi
|
||||
|
||||
# ── Phase 8: Ops bundle ────────────────────────────────────────────────────────
|
||||
|
||||
step "8 — Create ops bundle (age-encrypted snapshot)"
|
||||
|
||||
@@ -28,5 +28,12 @@ secrets_applied:
|
||||
enckey_bootstrapped: true
|
||||
pi_admin_created: true
|
||||
|
||||
# OpenBao init/unseal (NET-WP-0020 T2, sops-held-automation lane only).
|
||||
# false here because the current cluster's OpenBao was initialized via the
|
||||
# attended ceremony (NET-WP-0015–0017), not this automation path. These flip
|
||||
# to true only when Phase 7b runs on a greenfield rebuild.
|
||||
openbao_initialized: false
|
||||
openbao_post_unseal_verified: false
|
||||
|
||||
# Derived: all true → bootstrap complete
|
||||
bootstrap_complete: true
|
||||
|
||||
@@ -55,16 +55,24 @@ state_hub_task_id: "65407eb1-9d89-4158-aed5-4987badd83fc"
|
||||
(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)
|
||||
- [ ] Wire the helper as an optional phase inside `creds-bootstrap-agent.sh`
|
||||
(agent-policy blocked automated edits to the credential bootstrap script on
|
||||
2026-07-02 — operator should add a phase that calls the helper, sets the two
|
||||
state flags in `creds-state.yaml`, and re-runs `encrypt-secrets.sh` + commit
|
||||
when `secrets/openbao/` was created)
|
||||
- [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
|
||||
|
||||
Reference in New Issue
Block a user