Add versioned ephemeral custody lifecycle
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02669-87ee-7a31-b111-edc95a16e0fa
This commit is contained in:
parent
985cef2572
commit
30e6edc236
17 changed files with 2855 additions and 6 deletions
|
|
@ -13,6 +13,7 @@ related:
|
|||
- AUDIT-WP-0008
|
||||
- WH-ENG-20260822-AUDIT-E2-01
|
||||
- WH-ENG-20260822-AUDIT-E2-02
|
||||
- RAILIANCE-WP-0025
|
||||
origin: routed
|
||||
origin_ref: "State Hub messages 10f80080-4c83-42ba-8590-f23c582d9f05 and a93fa88f-a9c5-4539-93ae-0c8f8490f53d"
|
||||
state_hub_workstream_id: "88c4ef7f-0af8-580e-90dc-a2bae2675a4d"
|
||||
|
|
@ -47,7 +48,7 @@ lease revocation, firewall change, or host reboot.
|
|||
|
||||
```task
|
||||
id: RAILIANCE-WP-0024-T01
|
||||
status: wait
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "c4da371a-f35d-5377-9f6a-d34e274c98d0"
|
||||
```
|
||||
|
|
@ -93,8 +94,26 @@ projection gate is 19:15Z–19:18Z and cleanup must finish by 19:30Z. Platform
|
|||
tests (114), Whitehat tests (53), both Kubernetes server-side dry-runs, and a
|
||||
live value-safe preflight passed. At preflight there were no temporary token
|
||||
paths, projection resources, runner pod, or temporary sender identities, and
|
||||
no secret value was observed. This task remains `wait` until an attended
|
||||
operator invokes projection inside the gate and completes the cleanup receipt.
|
||||
no secret value was observed. At that pre-run point the task remained `wait`
|
||||
until an attended operator invoked projection and completed the cleanup receipt.
|
||||
|
||||
**Terminal result (2026-08-22):** projection succeeded at 19:17:54Z with
|
||||
exactly two bounded identities and the two declared mounted keys. Whitehat
|
||||
failed closed before traffic because its live broker could not consume the
|
||||
value-safe platform receipt; the runner sent zero target packets and was
|
||||
deleted at 19:21:07Z. Exact cleanup completed at 19:21:39Z and independent
|
||||
preflight proved no temporary identity, KV path, ESO resource, mounted Secret,
|
||||
or runner remained; audit-core was `1/1` Ready and no secret value was
|
||||
observed. The first attempt also proved automatic rollback when SSH shell
|
||||
expansion corrupted a Go-template argument; commit `d239ed3` fixes that defect.
|
||||
|
||||
T01 is done because the mount-only projection, application expiry, reload,
|
||||
abort, and cleanup lane is implemented and live-proven. The missing consumable
|
||||
broker contract is not carried as prose in this completed task: versioned
|
||||
receipts, the pre-projection broker gate, generic lifecycle, and future expired
|
||||
cleanup interface are implemented under `RAILIANCE-WP-0025`. The dated `-01`
|
||||
and `-02` procedures are terminal evidence/cleanup references and must not be
|
||||
copied for another engagement.
|
||||
|
||||
## T02 — Define the runtime database lease recovery exercise
|
||||
|
||||
|
|
@ -260,7 +279,7 @@ each task.
|
|||
|
||||
## Acceptance
|
||||
|
||||
- [ ] E2 cannot proceed without enforced sender expiry and exact-path projection.
|
||||
- [x] E2 cannot proceed without enforced sender expiry and exact-path projection.
|
||||
- [ ] Database recovery is restart-free and evidenced without credential values.
|
||||
- [ ] Reboot recovery has an ordered, owner-signed checklist and abort path.
|
||||
- [ ] No live action is implied by completing this design workplan.
|
||||
- [x] No live action is implied by completing this design workplan.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,158 @@
|
|||
---
|
||||
id: RAILIANCE-WP-0025
|
||||
type: workplan
|
||||
title: "Version ephemeral custody projection and broker handoff"
|
||||
domain: financials
|
||||
repo: railiance-platform
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: railiance
|
||||
created: "2026-08-22"
|
||||
updated: "2026-08-22"
|
||||
related:
|
||||
- RAILIANCE-WP-0024
|
||||
- WHITEHAT-WP-0001
|
||||
- AUDIT-WP-0008
|
||||
origin: run-review
|
||||
origin_ref: "WH-ENG-20260822-AUDIT-E2-02 terminal clean admission abort"
|
||||
---
|
||||
|
||||
# RAILIANCE-WP-0025 — Version ephemeral custody projection and broker handoff
|
||||
|
||||
## Goal
|
||||
|
||||
Replace engagement-specific credential scripts and prose handoffs with one
|
||||
versioned, value-safe, fail-closed lifecycle. A consumer must prove it can
|
||||
consume the projection receipt before platform custody mints anything. The
|
||||
platform then exposes direct `preflight`, `project`, `status`, `cleanup`, and
|
||||
expired-lease cleanup interfaces without transferring bearer values or
|
||||
collapsing owner approvals.
|
||||
|
||||
The implementation is repository code and contracts only. It does not
|
||||
authorize or schedule a live credential projection, workload, probe, or
|
||||
unattended cleanup controller.
|
||||
|
||||
## T01 — Define projection, broker-readiness, and cleanup receipts
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-0025-T01
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Publish versioned JSON Schemas and canonical validation for the projection
|
||||
contract, broker-readiness receipt, active projection receipt, and cleanup
|
||||
receipt. Bind every receipt to the exact engagement, target revision and image,
|
||||
runner and target contract digests, mounted identity handles, expiry, opaque
|
||||
lease id, and cleanup authority. Values and value-derived fingerprints are
|
||||
forbidden.
|
||||
|
||||
Done when malformed, stale, mismatched, expired, and value-bearing documents
|
||||
fail closed and consumers can implement without interpreting prose.
|
||||
|
||||
Implemented in four JSON Schemas plus `scripts/custody_contract.py`. Canonical
|
||||
projection ids cover all receipt content; validators bind target, contract,
|
||||
roles, mount paths, resource names and UIDs, and reject value-bearing fields.
|
||||
Broker approvals also pin the current hashes of all four interface schemas.
|
||||
|
||||
## T02 — Implement a data-driven custody lifecycle
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-0025-T02
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Replace copied per-engagement code and static manifests with one lifecycle that
|
||||
derives exact OpenBao and ESO resources from a validated engagement contract.
|
||||
Expose value-safe `preflight`, `project`, `status`, and idempotent `cleanup`
|
||||
commands. Preserve the existing two-identity sender overlay, application-level
|
||||
expiry, exact-key mount, readiness reload, and exact-scope rollback behavior.
|
||||
|
||||
Done when a new engagement requires data only, not copied Python, HCL, or YAML,
|
||||
and an old engagement identifier cannot leak into generated resources.
|
||||
|
||||
Implemented by `scripts/custody-projection.py` and the intentionally invalid
|
||||
placeholder template `docs/custody-projection-contract.example.json`. Policy,
|
||||
role, store, KV paths, ExternalSecret data mappings, sender overlays, expiry,
|
||||
and cleanup scope derive from one validated contract. Resource names use an
|
||||
engagement-id digest rather than a copied run suffix.
|
||||
|
||||
## T03 — Gate projection on a direct broker capability receipt
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-0025-T03
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Provide a direct owner interface for `whitehat-security` to inspect, verify,
|
||||
approve, or request changes to the contract. Approval must identify the tested
|
||||
adapter revision and artifact digest and be posted directly to State Hub. The
|
||||
platform lifecycle must find a current matching approval before generating a
|
||||
credential.
|
||||
|
||||
Done when an unconnected, stale, wrong-engagement, or wrong-contract broker is
|
||||
rejected before the first OpenBao or sender-registry mutation.
|
||||
|
||||
Implemented by `scripts/wp0025-broker-readiness.py`. Its closed verification
|
||||
surface pins Whitehat's adapter and focused test paths, computes their commit
|
||||
and digest, runs only the named focused test, and posts the canonical receipt
|
||||
directly as `whitehat-security`. `project` checks State Hub before reading the
|
||||
platform-admin token file, generating bearer values, or touching live state.
|
||||
No adapter approval is fabricated by this implementation; a future Whitehat
|
||||
adapter must pass the interface itself.
|
||||
|
||||
## T04 — Harden execution and transactional cleanup
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-0025-T04
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Centralize remote argv quoting, test shell-hostile arguments, and inject
|
||||
failures at each mutation boundary. Prove that partial projection invokes exact
|
||||
cleanup and that status never infers absence after a connectivity failure.
|
||||
Retire the copied `-01`/`-02` procedure from future-run instructions.
|
||||
|
||||
Done when the SSH expansion defect from the `-02` run and every modeled partial
|
||||
failure have regression coverage.
|
||||
|
||||
Implemented by `scripts/remote_exec.py` and focused tests covering `$`, shell
|
||||
substitution, semicolons, quotes, NUL refusal, and value-safe failure messages.
|
||||
The lifecycle uses a transaction whose rollback is exercised after every
|
||||
modeled mutation boundary. Connectivity failure cannot be interpreted as
|
||||
absence, and cleanup refuses a recreated same-name Kubernetes resource whose
|
||||
UID differs from the receipt.
|
||||
|
||||
## T05 — Add an approval-ready expired-lease cleanup entry point
|
||||
|
||||
```task
|
||||
id: RAILIANCE-WP-0025-T05
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Add a fail-closed `cleanup-expired` interface that accepts only a valid
|
||||
projection receipt after its expiry, removes only the receipt-bound resources,
|
||||
and emits the normal cleanup receipt. Do not install a scheduler or controller;
|
||||
deployment of unattended cleanup remains a separate owner decision.
|
||||
|
||||
Done when an approved future reaper can call a deterministic command without
|
||||
receiving projected bearer values or reconstructing cleanup scope from chat.
|
||||
|
||||
Implemented as `cleanup-expired`. It refuses before expiry, requires the exact
|
||||
canonical projection receipt and engagement confirmation, verifies live UIDs,
|
||||
uses the ordinary exact cleanup transaction, and emits the versioned cleanup
|
||||
receipt. No scheduler, controller, runtime identity, or unattended authority
|
||||
was deployed; those remain a separate owner decision.
|
||||
|
||||
## Acceptance
|
||||
|
||||
- [x] No projection can begin without a current consumer broker receipt.
|
||||
- [x] A new engagement is configuration, not copied executable code.
|
||||
- [x] Projection and cleanup receipts are versioned, canonical, and value-safe.
|
||||
- [x] Remote command arguments survive shell-hostile templates unchanged.
|
||||
- [x] Every modeled partial mutation cleans only its receipt-bound scope.
|
||||
- [x] Expired cleanup is executable but no unattended scheduler is deployed.
|
||||
Loading…
Add table
Add a link
Reference in a new issue