From 238d2615361060c7a2f39015ba83e8a655bead61 Mon Sep 17 00:00:00 2001 From: codex Date: Sat, 5 Sep 2026 16:43:47 +0200 Subject: [PATCH] fix: preserve unrelated live boundary rules during signing lane apply Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ed7-828d-7ca0-a8d4-0c3e5a0c4102 --- .../state-hub-preflight-activation.md | 11 +++++++++++ .../state-hub-preflight-boundary-baseline.sha256 | 2 +- openbao/state-hub-preflight/agent-deny-overlay.hcl | 7 +++++++ scripts/state_hub_preflight_lane.py | 8 +++++--- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 openbao/state-hub-preflight/agent-deny-overlay.hcl diff --git a/docs/credential-lane-designs/state-hub-preflight-activation.md b/docs/credential-lane-designs/state-hub-preflight-activation.md index b222942..8366df9 100644 --- a/docs/credential-lane-designs/state-hub-preflight-activation.md +++ b/docs/credential-lane-designs/state-hub-preflight-activation.md @@ -96,3 +96,14 @@ custody for reviewed recovery. Never restore a compromised predecessor key. T04 remains open until live custody/auth negatives, ESO delivery, API-only exposure, all-replica equality, signed preflight, rotation/invalidation and recovery receipts pass. Source tests and server dry-run alone are preparation. + +## Live policy drift review + +The first contained apply refused before mutation because the live shared +boundary lacks the source-only Policy Nexus data/metadata denies. A separate +contained metadata read confirmed that exact difference. The reviewed writer +now pins the observed live baseline and appends only `agent-deny-overlay.hcl`, +preserving every unrelated live rule. It does not deploy the pending Policy +Nexus source-only change as part of this lane. The global source policy retains +its desired rules; live parity for that other lane remains a platform assurance +observation, not an acceptance claim here. diff --git a/openbao/policies/inputs/state-hub-preflight-boundary-baseline.sha256 b/openbao/policies/inputs/state-hub-preflight-boundary-baseline.sha256 index 0bc12bd..e2e92f8 100644 --- a/openbao/policies/inputs/state-hub-preflight-boundary-baseline.sha256 +++ b/openbao/policies/inputs/state-hub-preflight-boundary-baseline.sha256 @@ -1 +1 @@ -8cbbe133516466bd70ee412fb2214fbe3d1fe5d455f513186eb149743a30636d +cec0e5f0f3a6bd2a8ed077805c0c2534bd03bdfa7cb45ac1f4ac90eee354ac0d diff --git a/openbao/state-hub-preflight/agent-deny-overlay.hcl b/openbao/state-hub-preflight/agent-deny-overlay.hcl new file mode 100644 index 0000000..01920c1 --- /dev/null +++ b/openbao/state-hub-preflight/agent-deny-overlay.hcl @@ -0,0 +1,7 @@ +# RPF-WP-0035-T04: preflight signing key is API-only. +path "platform/data/workloads/state-hub/repository-rename-preflight" { + capabilities = ["deny"] +} +path "platform/metadata/workloads/state-hub/repository-rename-preflight" { + capabilities = ["deny"] +} diff --git a/scripts/state_hub_preflight_lane.py b/scripts/state_hub_preflight_lane.py index c36e30b..1dfb7f8 100644 --- a/scripts/state_hub_preflight_lane.py +++ b/scripts/state_hub_preflight_lane.py @@ -167,12 +167,14 @@ def run(args, receipt): if args.expected_version != 0: raise LaneError('bootstrap_requires_cas_zero') # Refuse drift rather than overwriting another operator's policy. - boundary = ROOT / 'openbao/policies/agent-high-risk-boundary.hcl' + overlay = (ROOT / 'openbao/state-hub-preflight/agent-deny-overlay.hcl').read_text() current = data(bao(['read', '-format=json', 'sys/policies/acl/agent-high-risk-boundary']))['data']['policy'] baseline = (ROOT / 'openbao/policies/inputs/state-hub-preflight-boundary-baseline.sha256').read_text().strip() - if current != boundary.read_text() and hashlib.sha256(current.encode()).hexdigest() != baseline: + if hashlib.sha256(current.encode()).hexdigest() != baseline: raise LaneError('boundary_policy_drift') - bao(['write', 'sys/policies/acl/agent-high-risk-boundary', '-'], payload={'policy': boundary.read_text()}) + # Preserve live unrelated policy verbatim; add only the reviewed lane. + bao(['write', 'sys/policies/acl/agent-high-risk-boundary', '-'], + payload={'policy': current + '\n' + overlay}) existing = bao(['read', '-format=json', 'auth/kubernetes/role/' + ROLE], allow_failure=True) if existing.returncode == 0: raise LaneError('role_already_exists_review_partial_apply')