RPF-WP-0015-T03: attended OpenBao reboot snapshot lane with mandatory off-OpenBao escrow
Silent contained child: raft snapshot via tunnel, age to offsite (+custodian) recipients, in-memory escrow decrypt proof (founder decision recorded), If-None-Match upload to openbao/, receipt self-validated. Preflight now rejects snapshot receipts without a decryption key held outside OpenBao. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 680842@bnt-lap001 Assistant-Session: 54eb9e8e-7d6b-4f0c-b7a6-a6db62075883
This commit is contained in:
parent
64292531ce
commit
133628c573
8 changed files with 855 additions and 4 deletions
|
|
@ -129,6 +129,44 @@ State Hub.
|
|||
Pass that receipt to the preflight with
|
||||
`--openbao-snapshot-evidence /path/to/receipt.json`; a merely existing,
|
||||
stale, placeholder, wrong-cluster, unencrypted, or on-host receipt is denied.
|
||||
|
||||
The reviewed lane is `make openbao-reboot-snapshot` (offline tests:
|
||||
`make openbao-reboot-snapshot-test`). It runs
|
||||
`scripts/openbao-reboot-snapshot.py` as the single silent child of the
|
||||
contained `openbao-platform-admin-login` (via
|
||||
`scripts/openbao-attended-exec.py`):
|
||||
|
||||
```bash
|
||||
make openbao-reboot-snapshot \
|
||||
SNAPSHOT_SCENARIO_ID=RPF-WP-0015-T03-<scenario> \
|
||||
SNAPSHOT_RECEIPT=/abs/new/receipt.json \
|
||||
SNAPSHOT_CUSTODIAN_ESCROW_REF=<where a decryption key is held outside OpenBao> \
|
||||
SNAPSHOT_CUSTODIAN_RECIPIENT=age1... # only if that offline key differs from the offsite recipient
|
||||
SNAPSHOT_PRIVATE_DIR=/abs/0700/dir # optional; default is the session HOME (prefer tmpfs)
|
||||
```
|
||||
|
||||
Recoverability requires a decryption key held outside OpenBao: the escrow
|
||||
reference is mandatory and the preflight rejects a receipt without one. If the
|
||||
custodian's offline key is the offsite recipient, the reference alone is
|
||||
recorded; otherwise the snapshot is also encrypted to
|
||||
`SNAPSHOT_CUSTODIAN_RECIPIENT` (age: any one recipient key decrypts). The
|
||||
receipt lists all recipients. Reading the offsite `AGE_PRIVATE_KEY` for the
|
||||
decrypt-stream proof is a founder decision (in memory only), recorded in
|
||||
`reviews/RPF-WP-0015-T03-founder-go-20261014.json#escrow_key_read` and cited by
|
||||
the receipt. Snapshots upload to the founder-created `openbao/` folder.
|
||||
|
||||
In order it reads `bao status` (initialized, unsealed, Raft), saves the
|
||||
snapshot through the tunnel into a fresh 0700 temp dir outside Git, re-reads
|
||||
status (same `cluster_id`, index not behind), age-encrypts to the offsite
|
||||
lane recipient declared in `lib/railiance-backup-common.sh` (plus the custodian
|
||||
recipient, if given), proves the
|
||||
lane's escrow key derives that recipient and decrypt-streams the ciphertext
|
||||
to the plaintext sha256, then uploads ciphertext only to the governed
|
||||
Nextcloud lane with `If-None-Match: *`. The temp dir is always shredded.
|
||||
The receipt (0600, `encrypted_location_ref`
|
||||
`offhost-custody:<scenario>:<ts>`) is self-checked with the preflight's own
|
||||
validator before it is written; on any failure the file holds a value-safe
|
||||
`status: failed` record instead, which the preflight rejects.
|
||||
7. Have both Shamir share custodians present. Prove provider-console access and
|
||||
SSH access (same-day `RAIL01-CONSOLE-*` receipt). Record the exact restart
|
||||
operator, abort operator, and the railiance-infra independent abort owner.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue