From 022cf4b72799befa1f52f704548fa078847150e6 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 5 Sep 2026 18:30:49 +0200 Subject: [PATCH] fix: require signature invalidation in live rotation acceptance Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ed7-828d-7ca0-a8d4-0c3e5a0c4102 --- ...pendent-signing-verification-20260905.json | 21 +++++++++++++++++++ scripts/verify_preflight_signing_runtime.py | 8 ++++--- ...88-preflight-signing-runtime-acceptance.md | 14 +++++++++---- 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 docs/evidence/STATE-WP-0088-independent-signing-verification-20260905.json diff --git a/docs/evidence/STATE-WP-0088-independent-signing-verification-20260905.json b/docs/evidence/STATE-WP-0088-independent-signing-verification-20260905.json new file mode 100644 index 0000000..1454736 --- /dev/null +++ b/docs/evidence/STATE-WP-0088-independent-signing-verification-20260905.json @@ -0,0 +1,21 @@ +{ + "schema": "state-hub.signing-runtime-acceptance.v1", + "health": "passed", + "signed_preflight": true, + "replicas": 1, + "secret_resource_version": "57239554", + "pods": [ + { + "pod_uid": "cff7074b-5d15-40b9-8c14-68c1c3ab05c3", + "accepted_key_version": true, + "predecessor_rejected": true + } + ], + "repository_mutations": 0, + "date": "2026-09-05", + "task": "STATE-WP-0088-T02", + "platform_task": "RPF-WP-0035-T04", + "verified_kv_version": 2, + "predecessor_rejection": "signature; expiry alone is rejected by the verifier", + "platform_evidence": "railiance-platform/docs/evidence/RPF-WP-0035-T04-signing-activation-2026-09-05.json" +} diff --git a/scripts/verify_preflight_signing_runtime.py b/scripts/verify_preflight_signing_runtime.py index 9b3474a..3b1f607 100644 --- a/scripts/verify_preflight_signing_runtime.py +++ b/scripts/verify_preflight_signing_runtime.py @@ -2,7 +2,6 @@ """Non-mutating live signing acceptance. Prints metadata and booleans only.""" import argparse import base64 -from datetime import datetime, timedelta, timezone import hashlib import hmac import json @@ -33,6 +32,8 @@ def main(): replicas = deployment['spec']['replicas'] assert replicas > 0 and len(pods) == replicas health = json.load(urllib.request.urlopen('http://127.0.0.1:8000/state/health', timeout=20)) + assert health['status'] == 'ok' and health['db'] == 'connected' + assert health['instance_role'] == 'primary' and health['instance_label'] == 'railiance01' # Fixture is read-only and is the existing consuming migration's source ID. req = urllib.request.Request( 'http://127.0.0.1:8000/repos/fda8ad85-a7d7-4055-8f21-902a533e59df/rename/preflight', @@ -59,8 +60,9 @@ _verify_preflight_token(payload['token']) if payload['predecessor']: try: _verify_preflight_token(payload['predecessor']) - except RenamePreconditionFailed: - pass + except RenamePreconditionFailed as error: + if str(error) != 'Invalid repository rename preflight token': + raise RuntimeError('predecessor_rejection_was_not_signature_invalidation') else: raise RuntimeError('predecessor_not_invalidated') print('verified') diff --git a/workplans/STATE-WP-0088-preflight-signing-runtime-acceptance.md b/workplans/STATE-WP-0088-preflight-signing-runtime-acceptance.md index 5f587e8..2b98803 100644 --- a/workplans/STATE-WP-0088-preflight-signing-runtime-acceptance.md +++ b/workplans/STATE-WP-0088-preflight-signing-runtime-acceptance.md @@ -43,16 +43,16 @@ priority: high state_hub_task_id: "55b32d0d-d30a-50c2-bae0-d6e3a357e6d1" ``` -Fresh live flex-auth -> access-engine preflight returns exactly the -`preflight_signing_unavailable` blocker. Target is primary/railiance01, +Before activation, the live flex-auth -> access-engine preflight returned +exactly the `preflight_signing_unavailable` blocker. Target is primary/railiance01, namespace/release/deployment state-hub, current API SA state-hub and one replica. After platform custody verification, enable the chart, prove API-only delivery, all-replica key equality, health and non-mutating signed preflight. Then stop all API replicas (including terminating pods), rotate with CAS through platform, wait ESO, restart and prove predecessor invalidation and forward recovery. Runbook: railiance-platform/docs/credential-lane-designs/state-hub-preflight-activation.md. -No repository rename is in scope. Live completion is pending attended OpenBao -OIDC/MFA; ambient session returned 403. +No repository rename is in scope. Initial activation required attended OpenBao +OIDC/MFA because the ambient session returned 403; completion is recorded below. Completed 2026-09-05 under the user's instruction to lead activation from @@ -69,3 +69,9 @@ Evidence is owned by platform: `railiance-platform/docs/evidence/RPF-WP-0035-T04-signing-activation-2026-09-05.json`. Protected predecessor fixture removed after verification. No residual scope; the consuming FLEX-WP-0020 cutover remains separately governed. + +Independent review reverified the new API replica against the materialized key +and the predecessor captured before rotation. The verifier now rejects expiry +as sufficient rotation evidence and also requires primary/railiance01 health. +Receipt: `docs/evidence/STATE-WP-0088-independent-signing-verification-20260905.json`. +The private predecessor token was removed after this verification.