feat: verify live KeyCape custody and preserve versions on resume
Assistant: codex Assistant-Model: gpt-5.6-luna Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
b7861de20e
commit
c6dc4286e2
8 changed files with 382 additions and 57 deletions
|
|
@ -62,6 +62,36 @@ def contracts():
|
|||
return result
|
||||
|
||||
|
||||
|
||||
def resume_provision(lanes, receipt, prior_path):
|
||||
prior = json.loads(Path(prior_path).read_text())
|
||||
require(prior.get('status') == 'failed' and prior.get('verifier_delivery_disabled_custody_versions_retained')
|
||||
and prior.get('keycape', {}).get('compatible_pair_restored'), 'verified_partial_activation_receipt_required')
|
||||
old_rows = prior['lanes']
|
||||
require(len(old_rows) == len(lanes), 'partial_receipt_lane_mismatch')
|
||||
for lane, old in zip(lanes, old_rows):
|
||||
require(old['ccr'] == lane['ccr'] and (old.get('custody_seeded') or old.get('existing_version_reused')) and old.get('kv_version') == 1,
|
||||
'initial_version_provenance_required')
|
||||
metadata = read_optional(lane['metadata'])
|
||||
require(metadata is not None and metadata['current_version'] == 1
|
||||
and not metadata['versions']['1'].get('destroyed') and not metadata['versions']['1'].get('deletion_time'),
|
||||
'initial_custody_version_changed')
|
||||
role = read_optional('auth/kubernetes/role/' + lane['role'])
|
||||
require(role is not None and role.get('token_policies') == []
|
||||
and role_matches(dict(role, token_policies=[lane['policy']]), lane), 'disabled_role_drift')
|
||||
require(read_optional('sys/policies/acl/' + lane['policy'])['policy'] == lane['hcl'], 'resume_policy_drift')
|
||||
require(all(re.search(r'path\s+"' + re.escape(path) + r'"\s*\{\s*capabilities\s*=\s*\["deny"\]\s*\}', read_optional(BOUNDARY)['policy'])
|
||||
for path in (lane['kv'], lane['metadata'])), 'resume_boundary_drift')
|
||||
# Only reattach the same reviewed reader roles. No KV write, import or rotation.
|
||||
for lane, old in zip(lanes, old_rows):
|
||||
bao(['write', 'auth/kubernetes/role/' + lane['role'], '-'], payload=lane['role_payload'])
|
||||
require(role_matches(read_optional('auth/kubernetes/role/' + lane['role']), lane), 'resumed_role_readback_failed')
|
||||
receipt['lanes'].append({'ccr': lane['ccr'], 'source_sha256': lane['source_sha256'],
|
||||
'custody_seeded': False, 'existing_version_reused': True, 'kv_version': 1,
|
||||
'initial_request_id': old.get('initial_request_id', old.get('request_id')), 'policy_applied': False, 'role_applied': True})
|
||||
receipt['custody_versions_unchanged'] = True
|
||||
|
||||
|
||||
def read_optional(path):
|
||||
result = bao(['read', '-format=json', path], allow_failure=True)
|
||||
if result.returncode == 0:
|
||||
|
|
@ -264,8 +294,9 @@ def run(args, receipt):
|
|||
check = data(command(['python3', '-B', '/home/worsch/net-kingdom/sso-mfa/k8s/keycape/openbao-client-config.py', 'issuer-check-live'], env=env))
|
||||
require(check['issuer_matches'] and check['verified_issuer'] == 'https://auth.coulomb.social', 'verified_issuer_pin_required')
|
||||
receipt['issuer_pin_revision'] = check['before']['resource_version']
|
||||
rollout = load_rollout() if args.action == 'activate' else None
|
||||
rollout = load_rollout() if args.action in {'activate', 'resume-activate'} else None
|
||||
if rollout:
|
||||
rollout.verify_artifact()
|
||||
# Exercise config construction and API admission before any custody write.
|
||||
secret = rollout.get(kube, 'secret', 'keycape-config')
|
||||
dep = rollout.get(kube, 'deployment', 'keycape')
|
||||
|
|
@ -282,6 +313,9 @@ def run(args, receipt):
|
|||
receipt['phase'] = 'provision'
|
||||
if args.action in {'provision', 'activate'}:
|
||||
provision(lanes, receipt)
|
||||
elif args.action == 'resume-activate':
|
||||
require(args.prior_receipt, 'prior_receipt_required')
|
||||
resume_provision(lanes, receipt, args.prior_receipt)
|
||||
else:
|
||||
receipt['lanes'] = [{'ccr': lane['ccr']} for lane in lanes]
|
||||
receipt['phase'] = 'native_verification'
|
||||
|
|
@ -307,10 +341,11 @@ def run(args, receipt):
|
|||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description=__doc__)
|
||||
parser.add_argument('action', choices=['provision', 'verify', 'activate'])
|
||||
parser.add_argument('action', choices=['provision', 'verify', 'activate', 'resume-activate'])
|
||||
parser.add_argument('--kubeconfig', required=True)
|
||||
parser.add_argument('--receipt', required=True)
|
||||
parser.add_argument('--recovery')
|
||||
parser.add_argument('--prior-receipt')
|
||||
args = parser.parse_args()
|
||||
receipt = {'schema': 'platform.keycape-approval-custody.v1', 'status': 'failed', 'lanes': [],
|
||||
'started_at': datetime.now(timezone.utc).isoformat(), 'credential_values_emitted': False,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue