Harden WP-0024 recovery execution gates
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa
This commit is contained in:
codex 2026-08-22 14:00:18 +02:00
parent 08a3dd7660
commit 3f9e4535d1
10 changed files with 848 additions and 22 deletions

View file

@ -0,0 +1,29 @@
{
"procedure": "audit-core-database-lease-recovery",
"task_id": "RAILIANCE-WP-0024-T02",
"status": "pending",
"approval_id": null,
"window": {
"start": null,
"end": null
},
"abort_operator": null,
"owners": {
"audit-core": {
"acknowledged": false,
"message_id": null
},
"rapp-postgres": {
"acknowledged": false,
"message_id": null
},
"railiance-platform": {
"acknowledged": false,
"message_id": null
}
},
"synthetic_load": {
"contract_id": null,
"driver_revision": null
}
}

View file

@ -29,6 +29,25 @@ The result must have `automated_checks_passed: true`. It will remain
provided. The helper reads Secret metadata and key names only; it never reads
Secret data.
The live harness is
`scripts/audit-core-database-lease-recovery.py`. Start from the deliberately
pending `docs/audit-core-database-lease-approval.example.json`; the actual
value-safe receipt must name a ≤15-minute window, approval id, abort operator,
State Hub acknowledgement ids from audit-core/rapp-postgres/platform, and an
approved synthetic-load contract plus driver revision. Validate without
mutation:
```bash
make audit-database-lease-approval-check \
AUDIT_DATABASE_LEASE_APPROVAL=/path/to/approved-receipt.json
```
The separately approved load driver is an executable that accepts `baseline`,
`expect-unavailable`, `expect-recovered`, and `cleanup`, plus
`--contract-id ID`. Each call returns only its exact value-safe JSON evidence
shape. Unexpected keys—including a bearer accidentally returned as `token`
make the harness fail without echoing driver output.
## Attended sequence
Keep one terminal attached from baseline through recovery. A value-handling
@ -41,11 +60,14 @@ bodies and clear all transient JSON from memory or mode-`0600` temporary files.
2. Start bounded retrying synthetic traffic. Its evidence records only request
identifier, attempt time, response class, and final accepted/duplicate
result—never the bearer or payload.
3. Inside the attended process, read the current mounted username without
emitting it. List only lease handles below
`sys/leases/lookup/database/creds/audit-core-runtime`, look each up, and
retain the one handle whose lease username matches. Abort unless exactly one
live handle matches. Clear every lookup response and username immediately.
3. Inside the attended process, list only lease handles below
`sys/leases/lookup/database/creds/audit-core-runtime`. OpenBao's lease lookup
returns issue/expiry/TTL metadata but not the leased username, so exact
selection is deliberately stricter: there must be exactly one live handle
under that exact runtime prefix, and its issue/expiry interval must contain
the current database Secret refresh time. Abort for database-owner
disambiguation if zero or multiple handles exist. Retain only a one-way
handle fingerprint in evidence and clear the lookup response immediately.
4. Recheck that the Secret `resourceVersion`, pod UID, and selected handle have
not changed. Revoke only that handle. Do not revoke the role prefix and do
not revoke the ESO parent token.
@ -64,6 +86,20 @@ bodies and clear all transient JSON from memory or mode-`0600` temporary files.
the predecessor lease is revoked. The replacement remains managed by ESO
and expires through its normal database role TTL.
Only inside the approved window, with the receipt and reviewed driver:
```bash
make audit-database-lease-recovery-exercise \
AUDIT_DATABASE_LEASE_APPROVAL=/path/to/approved-receipt.json \
AUDIT_DATABASE_LEASE_DRIVER=/path/to/approved-load-driver
```
The exact confirmation string is embedded in the target. The harness rechecks
the Secret/pod/lease immediately before revocation, requires at least five
minutes of remaining lease TTL to avoid the normal ESO refresh race, performs
best-effort forced reconciliation on an interrupted post-revocation run, and
never issues a rollout/restart command.
## Time bounds and abort path
- Planned outage observation: at most 120 seconds.

View file

@ -0,0 +1,22 @@
{
"receipt_version": 1,
"receipt_id": "replace-with-operator-receipt-id",
"created_at": "YYYY-MM-DDTHH:MM:SSZ",
"operator": "replace-with-operator-id",
"source_cluster": "railiance01",
"source_namespace": "openbao",
"source_pod": "openbao-0",
"cluster_id": "replace-with-live-openbao-cluster-id",
"raft_applied_index": 0,
"snapshot_created": false,
"source_initialized": false,
"source_unsealed": false,
"snapshot_sha256": "sha256:0000000000000000000000000000000000000000000000000000000000000000",
"snapshot_encrypted": false,
"encrypted_snapshot_sha256": "sha256:1111111111111111111111111111111111111111111111111111111111111111",
"encrypted_location_ref": "replace-with-approved-off-host-custody-handle",
"encrypted_copy_off_host": false,
"encryption_verified": false,
"hash_verified": false,
"no_secret_material_recorded": false
}

View file

@ -38,7 +38,9 @@ the reviewed 1/1 Ready audit-core image. The following are human gates and make
- approved window id and acknowledgements from all five owners;
- a named attended driver/abort operator;
- independent provider-console access, not SSH alone;
- a current non-secret OpenBao Raft snapshot evidence file;
- a current non-secret OpenBao Raft snapshot receipt that validates against
`docs/openbao-reboot-snapshot-receipt.example.json`, the live cluster id and
Raft index, and the default 24-hour freshness bound;
- explicit availability of two of three Shamir shares through their approved
out-of-band custody paths.
@ -58,6 +60,9 @@ State Hub.
verify an on-demand backup before continuing.
5. Create and escrow a fresh OpenBao Raft snapshot through the approved
encrypted backup lane. Record only its evidence receipt and verification.
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.
6. Have both Shamir share custodians present. Prove provider-console access and
SSH access. Record the exact restart and abort operators.
7. Re-run the preflight with the approval and attestation flags. The result