railiance-platform/tests/test_nk_bind_executor_custody.py
codex f3b0c4f4b2
Some checks failed
CI Smoke / host-smoke (push) Waiting to run
CI Smoke / container-smoke (push) Waiting to run
CCR intake gate / gate (push) Has been cancelled
RPF-WP-0069-T05/T09/T10: bounded executor credential go-live runbook (NK-WP-0056-T06)
- CCR-2026-0063: NetKingdom's answer recorded (ESO as drafted); delivery aligned to the
  Secret the rapp Job mounts (sso/bounded-executor-tokens, key audit-core); reader role in
  the CCR-2026-0033/0041/0060 shape (audience openbao, explicit max TTL, self-lifecycle);
  custody_procedure names audit-core's seeder (one seeder only).
- CCR-2026-0060: delivery block (store rendered from the issuer template); fence step named.
- manifests/nk-bind-executor-eso.yaml: two sso-restricted stores and ExternalSecrets.
- scripts/nk_bind_executor_custody.py plan|fence|verify with synthetic-fixture tests.
- Source coding-agent boundary carries the KeyCape nk-bind-executor-approval path.
- docs/credential-lane-designs/nk-bind-executor-go-live.md: exact founder sequence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 523928@bnt-lap001
Assistant-Session: 6c737afb-9c14-4152-9f02-477214b9c350
2026-11-04 01:59:30 +01:00

277 lines
14 KiB
Python

"""Synthetic-fixture tests for scripts/nk_bind_executor_custody.py; no OpenBao, cluster or credential."""
import base64
import copy
import io
import json
import os
from pathlib import Path
import subprocess
import sys
import tempfile
import unittest
from contextlib import redirect_stdout
from unittest.mock import patch
import yaml
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / 'scripts'))
import nk_bind_executor_custody as lane # noqa: E402
import keycape_issuer_eso # noqa: E402
AUDIT_CORE = Path(os.environ.get('AUDIT_CORE_SOURCE', ROOT.parent / 'audit-core'))
RAPP = ROOT.parent / 'rapp-bounded-executor'
def approved_module(mutate=None, drop=None):
module = lane.credential_module()
original = module.validate_ccr
def candidate(path):
ccr, errors, warnings = original(path)
ccr = copy.deepcopy(ccr)
ccr['status'] = 'approved'
ccr['openbao']['auth']['bound_claims_confirmed'] = True
owners = next(l['approvers'] for l in lane.LANES.values() if l['ccr'] == ccr['id'])
ccr['review']['comments'] = [{'reviewer': o, 'decision': 'approved'} for o in owners if o != drop]
if mutate:
mutate(ccr)
return ccr, errors, warnings
module.validate_ccr = candidate
return module
def ok(payload=None, stderr=b''):
return subprocess.CompletedProcess([], 0, json.dumps(payload).encode() if payload is not None else b'', stderr)
def missing():
return subprocess.CompletedProcess([], 2, b'', b'No value found at path')
class FakeBao:
"""Dictionary-backed KV v2 and sys/policies with CAS; records every write."""
def __init__(self, registry_rows, boundary='path "platform/data/x" { capabilities = ["deny"] }\n'):
self.kv = {lane.REGISTRY: {'version': 3, 'data': {'senders.json': json.dumps(registry_rows),
'other': 'kept'}}}
self.policies = {'agent-high-risk-boundary': boundary}
self.writes = []
self.fail_registry_cas = False
def __call__(self, args, payload=None, token=None, allow_failure=False):
if args[0] == 'read':
path = args[-1]
if path.startswith('sys/policies/acl/'):
name = path.rsplit('/', 1)[1]
return ok({'data': {'policy': self.policies[name]}}) if name in self.policies else missing()
if path.startswith('platform/metadata/'):
key = path.replace('platform/metadata/', 'platform/data/', 1)
if key not in self.kv:
return missing()
v = self.kv[key]['version']
return ok({'data': {'current_version': v, 'versions': {str(v): {}}}})
if path in self.kv:
entry = self.kv[path]
return ok({'data': {'data': entry['data'], 'metadata': {'version': entry['version']}}})
return missing()
if args[0] == 'write':
path = args[-2]
self.writes.append((path, copy.deepcopy(payload)))
if path.startswith('sys/policies/acl/'):
self.policies[path.rsplit('/', 1)[1]] = payload['policy']
return ok({})
cas = payload['options']['cas']
current = self.kv.get(path, {'version': 0})['version']
if cas != current or (path == lane.REGISTRY and self.fail_registry_cas):
return subprocess.CompletedProcess([], 2, b'', b'check-and-set parameter did not match')
self.kv[path] = {'version': current + 1, 'data': copy.deepcopy(payload['data'])}
return ok({'data': {'version': current + 1}, 'request_id': 'req-%d' % len(self.writes)})
raise AssertionError('unexpected bao call %r' % (args,))
EXISTING = [{'name': 'approval-engine', 'tokens': ['A' * 64], 'sources': ['approval-engine'],
'tenants': ['tenant:platform'], 'may_write': True, 'may_read': False},
{'name': 'informed-decision', 'tokens': ['B' * 64], 'sources': ['informed-decision'],
'tenants': ['tenant:platform'], 'may_write': True, 'may_read': False}]
class Contracts(unittest.TestCase):
def test_plan_checks_the_drafts_offline(self):
contract = lane.contracts(approved=False)
self.assertEqual(sorted(contract), ['audit', 'consumer', 'eso'])
out = io.StringIO()
with patch.object(lane, 'bao', side_effect=AssertionError('plan must not contact Bao')), redirect_stdout(out):
self.assertEqual(lane.main(['plan']), 0)
plan = json.loads(out.getvalue())
self.assertEqual(plan['lanes']['consumer']['role'],
'keycape-nk-bind-executor-approval-bounded-executor-workload-kv-read')
self.assertEqual(plan['lanes']['audit']['external_secret'], 'sso/bounded-executor-tokens')
def test_unapproved_requests_refuse(self):
module = lane.credential_module()
original = module.validate_ccr
def proposed(path):
ccr, e, w = original(path)
ccr = copy.deepcopy(ccr)
ccr['status'] = 'proposed'
return ccr, e, w
module.validate_ccr = proposed
with self.assertRaisesRegex(lane.LaneError, 'approved_ccr_required'):
lane.contracts(approved=True, module=module, git_check=lambda p: True)
def test_every_named_owner_must_approve(self):
for name, spec in lane.LANES.items():
for owner in spec['approvers']:
module = approved_module(drop=owner)
with self.assertRaisesRegex(lane.LaneError, 'named_owner_approvals_required'):
lane.contracts(approved=True, module=module, git_check=lambda p: True)
def test_unconfirmed_binding_or_uncommitted_ccr_refuses(self):
module = approved_module(lambda c: c['openbao']['auth'].update(bound_claims_confirmed=False))
with self.assertRaisesRegex(lane.LaneError, 'binding_unconfirmed'):
lane.contracts(approved=True, module=module, git_check=lambda p: True)
with self.assertRaisesRegex(lane.LaneError, 'ccr_not_committed'):
lane.contracts(approved=True, module=approved_module(), git_check=lambda p: False)
def test_drifted_coordinates_refuse_even_when_approved(self):
drifts = [lambda c: c['openbao'].update(kv_path='platform/workloads/keycape/forgejo'),
lambda c: c['openbao']['auth'].update(audience='vault'),
lambda c: c['openbao']['auth'].update(ttl='1h'),
lambda c: c['openbao']['auth']['bound_claims'].update(service_account_names=['default'])]
for drift in drifts:
with self.assertRaisesRegex(lane.LaneError, 'exact_contract_required'):
lane.contracts(approved=True, module=approved_module(drift), git_check=lambda p: True)
def test_approved_contract_passes(self):
contract = lane.contracts(approved=True, module=approved_module(), git_check=lambda p: True)
self.assertIn('auth/token/revoke-self', contract['audit']['hcl'])
class Fence(unittest.TestCase):
def test_appends_only_missing_denies_and_preserves_live_content(self):
live = 'path "platform/data/x" { capabilities = ["deny"] }\n' + lane.deny_line(lane.FENCED[2]) + '\n'
fake = FakeBao([], boundary=live)
receipt = {}
with patch.object(lane, 'bao', side_effect=fake):
lane.fence(receipt)
self.assertEqual(receipt['fence_lines_added'], 3)
after = fake.policies['agent-high-risk-boundary']
self.assertTrue(after.startswith(live))
for path in lane.FENCED:
self.assertIn(f'"{path}"', after)
lane.fence(receipt)
self.assertEqual(receipt['fence_lines_added'], 0)
self.assertEqual(len(fake.writes), 1)
def test_present_path_without_deny_refuses(self):
live = 'path "%s" { capabilities = ["read"] }\n' % lane.FENCED[0]
fake = FakeBao([], boundary=live)
with patch.object(lane, 'bao', side_effect=fake), self.assertRaisesRegex(lane.LaneError, 'boundary_path_drift'):
lane.fence({})
self.assertEqual(fake.writes, [])
def test_source_boundary_carries_the_same_denies(self):
source = (ROOT / 'openbao/policies/agent-high-risk-boundary.hcl').read_text()
for path in lane.FENCED:
self.assertIn(lane.deny_line(path), source)
class Registry(unittest.TestCase):
def test_snapshot_refuses_empty_duplicate_or_colliding_registry(self):
for rows in ([], EXISTING + [copy.deepcopy(EXISTING[0])],
EXISTING + [{'name': 'x', 'tokens': ['A' * 64]}]):
with patch.object(lane, 'bao', side_effect=FakeBao(rows)), self.assertRaises(lane.LaneError):
lane.registry_snapshot()
with patch.object(lane, 'bao', side_effect=FakeBao(EXISTING)):
self.assertEqual(lane.registry_snapshot()[0], 3)
def test_receiver_parser_accepts_the_row_with_the_declared_overlay(self):
if not (AUDIT_CORE / 'audit_core/senders.py').exists():
self.skipTest('audit-core source not checked out')
row = dict(lane.SENDER, tokens=['fixture-' + 'x' * 56])
overlay = (AUDIT_CORE / 'deploy/senders-scope.json').read_text()
self.assertIn(lane.SENDER['name'], [e['name'] for e in json.loads(overlay)])
probe = ('import json,sys\nfrom audit_core.senders import SenderRegistry\n'
'row,overlay=json.loads(sys.argv[1]),sys.argv[2]\n'
'r=SenderRegistry.from_env({"AUDIT_CORE_SENDERS":json.dumps([row]),"AUDIT_CORE_SENDERS_SCOPE":overlay})\n'
's=r.authenticate("Bearer "+row["tokens"][0])\n'
'print(json.dumps([s.secret_policy,s.permits_source("net-kingdom.bounded-executor"),'
's.permits_tenant("platform"),s.permits_tenant("tenant:platform"),s.may_read]))\n')
result = subprocess.run([sys.executable, '-c', probe, json.dumps(row), overlay], cwd=AUDIT_CORE,
capture_output=True, text=True)
if result.returncode != 0:
self.skipTest('audit-core dependencies unavailable: ' + result.stderr.strip().splitlines()[-1])
self.assertEqual(json.loads(result.stdout), ['reject', True, True, False, False])
class Manifests(unittest.TestCase):
docs = list(yaml.safe_load_all((ROOT / 'manifests/nk-bind-executor-eso.yaml').read_text()))
def test_keycape_delivery_is_the_platform_template_rendering(self):
store, external = keycape_issuer_eso.documents(lane.CLIENT_ID)
self.assertEqual(self.docs[0]['spec'], store['spec'])
self.assertEqual(self.docs[0]['metadata']['name'], store['metadata']['name'])
self.assertEqual(self.docs[1]['spec'], external['spec'])
self.assertEqual(self.docs[1]['metadata']['name'], external['metadata']['name'])
self.assertEqual(self.docs[1]['metadata']['namespace'], 'sso')
def test_each_store_matches_its_lane_and_delivers_one_field(self):
for (store, external), name in zip((self.docs[0:2], self.docs[2:4]), ('eso', 'audit')):
spec = lane.LANES[name]
auth = store['spec']['provider']['vault']['auth']['kubernetes']
self.assertEqual(store['metadata']['name'], spec['store'])
self.assertEqual(auth['role'], spec['role'])
self.assertEqual(auth['serviceAccountRef'], {'name': 'external-secrets', 'namespace': 'external-secrets',
'audiences': ['openbao']})
self.assertEqual(store['spec']['conditions'], [{'namespaces': ['sso']}])
self.assertEqual((external['metadata']['namespace'], external['metadata']['name']), spec['external_secret'])
self.assertEqual(external['spec']['data'], [{'secretKey': spec['secret_key'], 'remoteRef': {
'key': spec['kv'].removeprefix('platform/'), 'property': spec['fields'][0]}}])
def test_audit_secret_is_the_one_the_executor_job_mounts(self):
job = RAPP / 'templates/job.yaml'
if not job.exists():
self.skipTest('rapp-bounded-executor not checked out')
pod = list(yaml.safe_load_all(job.read_text()))[1]['spec']['template']['spec']
volume = next(v for v in pod['volumes'] if v['name'] == 'tokens')['secret']
self.assertEqual(volume['secretName'], lane.LANES['audit']['external_secret'][1])
self.assertEqual([i['key'] for i in volume['items']], [lane.LANES['audit']['secret_key']])
class Main(unittest.TestCase):
def test_refuses_outside_approval_and_never_prints_a_value(self):
with tempfile.TemporaryDirectory() as directory:
receipt = Path(directory) / 'r.json'
out = io.StringIO()
with patch.object(lane, 'bao', side_effect=AssertionError('must not contact Bao')), redirect_stdout(out):
code = lane.main(['fence', '--receipt', str(receipt)])
self.assertEqual(code, 1)
body = json.loads(receipt.read_text())
self.assertEqual(body['status'], 'refused')
self.assertEqual(oct(receipt.stat().st_mode & 0o777), '0o600')
self.assertEqual(out.getvalue(), '')
with redirect_stdout(io.StringIO()):
self.assertEqual(lane.main(['verify', '--receipt', str(receipt)]), 1) # existing receipt refused
class Verify(unittest.TestCase):
def test_delivered_audit_copy_must_hash_equal_custody(self):
token = 'T' * 64
self.assertEqual(lane.sha(token), lane.sha(base64.b64decode(base64.b64encode(token.encode()))))
self.assertNotEqual(lane.sha(token), lane.sha('U' * 64))
def test_role_readback_shape(self):
spec = lane.LANES['consumer']
good = {'bound_service_account_names': ['nk-bind-executor'], 'bound_service_account_namespaces': ['sso'],
'token_policies': [spec['policy']], 'audience': 'openbao', 'token_ttl': 900, 'token_max_ttl': 900,
'token_explicit_max_ttl': 900, 'token_no_default_policy': True}
self.assertTrue(lane.role_ok(good, spec))
for key, value in (('audience', ''), ('token_ttl', 3600), ('token_policies', [spec['policy'], 'x']),
('bound_service_account_namespace_selector', '{}'), ('token_period', 60)):
self.assertFalse(lane.role_ok(dict(good, **{key: value}), spec))
if __name__ == '__main__':
unittest.main()