Pin signing-lane writes to the verified primary cluster
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
parent
5d288938f7
commit
80793afe4f
5 changed files with 59 additions and 1 deletions
|
|
@ -24,6 +24,12 @@ cross-namespace store references. Coding-agent data AND metadata are denied.
|
|||
State Hub chart diff together. Confirm the dedicated SA binding and record
|
||||
CCR approval from the user's task authorization. Keep the lane non-resolvable.
|
||||
2. Commit/push the reviewed source in both repositories before live apply.
|
||||
Verify the selected kubeconfig reaches kube-system UID
|
||||
`a553c742-0115-43d4-99a4-a5ca56fe0786` using a metadata-only namespace GET.
|
||||
The writer enforces this identity before OpenBao access. The workstation's
|
||||
default config uses a local port forward; if that listener is unavailable,
|
||||
establish the approved cluster access path before starting attended login.
|
||||
Do not substitute another cluster's context to make the command succeed.
|
||||
3. Run the silent writer through the contained attended login envelope:
|
||||
|
||||
```sh
|
||||
|
|
|
|||
23
history/2026-09-05-preflight-signing-activation-readiness.md
Normal file
23
history/2026-09-05-preflight-signing-activation-readiness.md
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# Signing activation readiness — RPF-WP-0035-T04
|
||||
|
||||
The user requested completion of T04. Concurrent session work landed platform
|
||||
commit `5d28893` and prepared State Hub chart wiring and STATE-WP-0088. Avoid
|
||||
overlapping live activation with that session; no credential mutation or API
|
||||
outage was performed during this review.
|
||||
|
||||
Read-only SSH checks confirmed kube-system UID
|
||||
`a553c742-0115-43d4-99a4-a5ca56fe0786`, one ready State Hub API replica, image
|
||||
`main-cdff3b7`, and absence of ExternalSecret `state-hub-rename-preflight`.
|
||||
The default workstation kubeconfig used localhost port 16443, whose listener
|
||||
refused connection. The activation runbook now requires verified cluster access
|
||||
before login, and the writer refuses a different cluster before OpenBao access
|
||||
or key generation. A regression test covers this refusal.
|
||||
|
||||
Credential routing selected `openbao-platform-admin-login`, verdict
|
||||
`founder_required`, identity act `oidc_login`. This requires attended operator
|
||||
OIDC/MFA through the contained Warden envelope. It cannot be substituted with
|
||||
root or workload authority. No new login was initiated while the other session's
|
||||
activation ownership remained unconfirmed.
|
||||
|
||||
T04 remains in progress: live custody, ESO delivery, signed preflight, and
|
||||
fenced rotation/invalidation/recovery evidence remain outstanding.
|
||||
|
|
@ -19,6 +19,7 @@ FIELD = 'REPOSITORY_RENAME_PREFLIGHT_SECRET'
|
|||
POLICY = 'workload-kv-read-state-hub-rename-preflight'
|
||||
ROLE = 'state-hub-rename-preflight-eso'
|
||||
SA = 'state-hub-preflight-eso'
|
||||
CLUSTER_UID = 'a553c742-0115-43d4-99a4-a5ca56fe0786'
|
||||
|
||||
|
||||
class LaneError(Exception):
|
||||
|
|
@ -68,6 +69,12 @@ def approved_contract():
|
|||
return expected, policy
|
||||
|
||||
|
||||
def assert_cluster(kube):
|
||||
namespace = data(command(kube + ['get', 'namespace', 'kube-system', '-o', 'json']))
|
||||
if namespace.get('metadata', {}).get('uid') != CLUSTER_UID:
|
||||
raise LaneError('primary_cluster_identity_mismatch')
|
||||
|
||||
|
||||
def assert_fenced(kube):
|
||||
deployment = data(command(kube + ['-n', 'state-hub', 'get', 'deployment', 'state-hub', '-o', 'json']))
|
||||
pods = data(command(kube + ['-n', 'state-hub', 'get', 'pods', '-l', 'app=state-hub', '-o', 'json']))
|
||||
|
|
@ -147,10 +154,11 @@ def verify_access(kube, receipt):
|
|||
|
||||
def run(args, receipt):
|
||||
role, policy = approved_contract()
|
||||
kube = ['kubectl', '--kubeconfig', args.kubeconfig]
|
||||
assert_cluster(kube)
|
||||
identity = data(bao(['token', 'lookup', '-format=json']))['data']
|
||||
if 'platform-admin' not in identity['policies'] or 'root' in identity['policies']:
|
||||
raise LaneError('attended_platform_admin_required')
|
||||
kube = ['kubectl', '--kubeconfig', args.kubeconfig]
|
||||
if args.action == 'verify':
|
||||
verify_access(kube, receipt)
|
||||
receipt['status'] = 'custody_verified_pending_eso_and_api_acceptance'
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ class SigningLaneTests(unittest.TestCase):
|
|||
args = SimpleNamespace(action='rotate', expected_version=1, kubeconfig='/fixture')
|
||||
result = SimpleNamespace(stdout=json.dumps({'data': {'policies': ['platform-admin']}}).encode())
|
||||
with patch.object(lane, 'approved_contract', return_value=({}, '')), \
|
||||
patch.object(lane, 'assert_cluster'), \
|
||||
patch.object(lane, 'bao', return_value=result), \
|
||||
patch.object(lane, 'assert_fenced', side_effect=lane.LaneError('fence')), \
|
||||
patch.object(lane.secrets, 'token_hex') as generate:
|
||||
|
|
@ -76,6 +77,18 @@ class SigningLaneTests(unittest.TestCase):
|
|||
lane.run(args, {})
|
||||
generate.assert_not_called()
|
||||
|
||||
def test_wrong_cluster_precedes_any_openbao_access_or_generation(self):
|
||||
args = SimpleNamespace(action='provision', expected_version=0, kubeconfig='/fixture')
|
||||
response = SimpleNamespace(stdout=json.dumps({'metadata': {'uid': 'other-cluster'}}).encode())
|
||||
with patch.object(lane, 'approved_contract', return_value=({}, '')), \
|
||||
patch.object(lane, 'command', return_value=response), \
|
||||
patch.object(lane, 'bao') as access, \
|
||||
patch.object(lane.secrets, 'token_hex') as generate:
|
||||
with self.assertRaisesRegex(lane.LaneError, 'primary_cluster_identity_mismatch'):
|
||||
lane.run(args, {})
|
||||
access.assert_not_called()
|
||||
generate.assert_not_called()
|
||||
|
||||
def test_unapproved_key_format_or_policy_does_not_pass_contract(self):
|
||||
import tempfile, yaml
|
||||
ccr = copy.deepcopy(self.ccr)
|
||||
|
|
|
|||
|
|
@ -122,3 +122,11 @@ access checks and a non-mutating signed preflight pass; every API replica uses
|
|||
the accepted version; rotation/invalidation and recovery are evidenced. No
|
||||
repository rename is part of S3 lane acceptance. If demand is withdrawn, record
|
||||
the owning decision and cancel this task explicitly rather than provision it.
|
||||
|
||||
2026-09-05 continuation: verified the live primary cluster identity and healthy
|
||||
single API replica; the signing ExternalSecret is still absent. Added a writer
|
||||
guard against wrong-cluster kubeconfigs before any OpenBao access. The default
|
||||
workstation kubeconfig's local port-forward listener was unavailable. Activation
|
||||
still needs the contained attended OIDC/MFA login and the acceptance evidence
|
||||
above; source preparation is not live completion. See
|
||||
`history/2026-09-05-preflight-signing-activation-readiness.md`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue