net-kingdom/sso-mfa/k8s/keycape/openbao-negative-session.py
tegwick 7ceac4372d
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Publish reviewed bounded JWT ready handoff and retained owner history
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
2026-10-11 18:31:04 +02:00

860 lines
40 KiB
Python

#!/usr/bin/env python3
"""Founder-attended KEY39 lifecycle. Silent; private values never leave memory/K8s.
inspect is metadata-only (no Secret read). execute requires an exact approved
envelope, source/runtime pins and founder-held private tokens on stdin. No login,
custody fetch, production credential, role or policy mutation is implemented.
"""
import argparse
import base64
import copy
import hashlib
import importlib.util
import json
import math
import fcntl
import stat
import os
from pathlib import Path
import secrets
import signal
import subprocess
import threading
import time
from contextlib import contextmanager
import urllib.parse
import urllib.request
import urllib.error
import yaml
CLUSTER = 'a553c742-0115-43d4-99a4-a5ca56fe0786'
TARGET = 'sso/keycape'
PROPOSAL = 'KEY-WP-0039-T02/attended-lifecycle-v9-ready-input'
IDS = ['openbao-probe-' + c for c in ['aud', 'sub', 'tenant', 'roles', 'scope', 'expiry']]
ENVS = ['KEYCAPE_' + c.upper().replace('-', '_') + '_CLIENT_SECRET' for c in IDS]
TEMP = 'keycape-openbao-negative-key39'
BAO_ORIGINS = {'http://127.0.0.1:18200', 'http://openbao.openbao.svc:8200'}
REQUEST_DEADLINE = None
BUSINESS_MONOTONIC_DEADLINE = None
CLEANUP_MONOTONIC_DEADLINE = None
CLEANING = False
MAX_RESPONSE = 256 * 1024
HTTP_TOTAL_SECONDS = 15
CLEANUP_TOTAL_SECONDS = 300
HTTP_ABORT_SECONDS = 0.02
PRIVATE_INPUT_MAX_BYTES = 65536
PRIVATE_TOKEN_MAX_BYTES = 16384
PRIVATE_INPUT_TOTAL_SECONDS = 15
READY_SCHEMA = 'key39-private-input-ready/v1'
READY_MAX_BYTES = 4096
class Refused(Exception):
pass
def require(ok, reason):
if not ok:
raise Refused(reason)
def digest(data):
return hashlib.sha256(data).hexdigest()
def canonical(value):
return digest(json.dumps(value, sort_keys=True, separators=(',', ':')).encode())
def finite_number(value):
try:
return type(value) in (int, float) and math.isfinite(value)
except OverflowError:
return False
def read_json(raw):
def reject_constant(_):
raise Refused('nonfinite_json_constant')
return json.loads(raw, parse_constant=reject_constant)
def begin_cleanup():
global CLEANUP_MONOTONIC_DEADLINE
if CLEANUP_MONOTONIC_DEADLINE is None:
CLEANUP_MONOTONIC_DEADLINE = time.monotonic() + CLEANUP_TOTAL_SECONDS
def check_deadline():
if CLEANING:
require(CLEANUP_MONOTONIC_DEADLINE is not None
and time.monotonic() < CLEANUP_MONOTONIC_DEADLINE, 'cleanup_budget_expired')
return
if REQUEST_DEADLINE is not None and not CLEANING:
require(finite_number(REQUEST_DEADLINE), 'approved_window_invalid')
require(time.time() < REQUEST_DEADLINE, 'approved_window_expired')
if BUSINESS_MONOTONIC_DEADLINE is not None:
require(time.monotonic() < BUSINESS_MONOTONIC_DEADLINE, 'session_business_budget_expired')
def request_budget(cap, cleanup=False):
require(finite_number(cap) and 0 < cap <= 30, 'request_timeout_invalid')
budget = float(cap)
if cleanup or CLEANING:
if CLEANUP_MONOTONIC_DEADLINE is not None:
budget = min(budget, CLEANUP_MONOTONIC_DEADLINE - time.monotonic())
else:
check_deadline()
if REQUEST_DEADLINE is not None:
budget = min(budget, REQUEST_DEADLINE - time.time())
if BUSINESS_MONOTONIC_DEADLINE is not None:
budget = min(budget, BUSINESS_MONOTONIC_DEADLINE - time.monotonic())
require(budget > 0 and math.isfinite(budget), 'request_window_exhausted')
return budget
@contextmanager
def total_timeout(seconds):
"""Linux main-thread hard elapsed bound, including blocking headers/body reads."""
require(finite_number(seconds) and 0 < seconds <= 30, 'request_timeout_invalid')
require(threading.current_thread() is threading.main_thread()
and hasattr(signal, 'setitimer'), 'main_thread_linux_timer_required')
previous_timer = signal.getitimer(signal.ITIMER_REAL)
require(previous_timer == (0.0, 0.0), 'existing_alarm_timer_refused')
previous_handler = signal.getsignal(signal.SIGALRM)
def expired(*_):
raise Refused('request_total_timeout')
started = time.monotonic()
signal.signal(signal.SIGALRM, expired)
signal.setitimer(signal.ITIMER_REAL, seconds)
try:
yield
require(time.monotonic() - started <= seconds, 'request_total_timeout')
finally:
signal.setitimer(signal.ITIMER_REAL, 0)
signal.signal(signal.SIGALRM, previous_handler)
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, *args, **kwargs):
return None
class SessionTransport:
"""Fixed origins, no ambient proxy, bounded reads, same guards in cleanup."""
def __init__(self, bao_origin, receipt=None):
require(bao_origin in BAO_ORIGINS, 'bao_origin_invalid')
self.bao_origin = bao_origin
self.receipt = receipt if receipt is not None else {}
self.opener = urllib.request.build_opener(urllib.request.ProxyHandler({}), NoRedirect())
def request(self, url, *, data=None, headers=None, method='POST', timeout=15):
allowed = {'https://kc.coulomb.social/token',
'https://kc.coulomb.social/.well-known/openid-configuration',
self.bao_origin + '/v1/auth/keycape-services/login',
self.bao_origin + '/v1/auth/token/revoke-self',
self.bao_origin + '/v1/sys/health'}
require(url in allowed, 'http_target_not_reviewed')
require(method == ('GET' if url.endswith(('/.well-known/openid-configuration', '/v1/sys/health')) else 'POST'),
'http_method_not_reviewed')
cleanup = url.endswith('/v1/auth/token/revoke-self')
budget = request_budget(min(timeout, HTTP_TOTAL_SECONDS), cleanup=cleanup)
total_deadline = time.monotonic() + budget
req = urllib.request.Request(url, data=data, headers=headers or {}, method=method)
response, status, raw = None, None, None
try:
with total_timeout(budget):
try:
response = self.opener.open(req, timeout=budget)
except urllib.error.HTTPError as error:
response = error
except (urllib.error.URLError, OSError):
if url == self.bao_origin + '/v1/auth/keycape-services/login':
self.receipt['openbao_login_outcome_unknown'] = True
return None, b''
status = response.getcode()
raw = response.read(MAX_RESPONSE + 1)
require(len(raw) <= MAX_RESPONSE, 'http_response_oversized')
response.close()
response = None
if not cleanup:
check_deadline()
return status, raw
except Refused:
if url == self.bao_origin + '/v1/auth/keycape-services/login' and status in (None, 200):
# A late response cannot pass; preserve acquired-token cleanup when available.
if raw is not None and status == 200:
self.revoke_late_session(raw)
else:
self.receipt['openbao_login_outcome_unknown'] = True
raise
except (urllib.error.URLError, OSError):
if url == self.bao_origin + '/v1/auth/keycape-services/login':
if raw is not None and status == 200:
self.revoke_late_session(raw)
else:
self.receipt['openbao_login_outcome_unknown'] = True
return None, b''
except Exception:
if url == self.bao_origin + '/v1/auth/keycape-services/login':
if raw is not None and status == 200:
self.revoke_late_session(raw)
else:
self.receipt['openbao_login_outcome_unknown'] = True
raise Refused('http_response_failed') from None
finally:
if response is not None:
self.abort_response(response, total_deadline)
def abort_response(self, response, original_deadline):
"""One bounded exceptional close; never retry or reset the cleanup clock."""
self.receipt['http_abort_close_attempted'] = False
self.receipt['http_abort_close_succeeded'] = False
begin_cleanup()
try:
cap = request_budget(HTTP_ABORT_SECONDS, cleanup=True)
remaining = original_deadline - time.monotonic()
if remaining > 0:
cap = min(cap, remaining)
self.receipt['http_abort_close_attempted'] = True
with total_timeout(cap):
response.close()
self.receipt['http_abort_close_succeeded'] = True
except Exception:
self.receipt['http_response_abort_unconfirmed'] = True
raise Refused('http_response_abort_unconfirmed') from None
def revoke_late_session(self, raw):
self.receipt['late_acceptance_revoke_attempted'] = False
self.receipt['late_acceptance_revoke_succeeded'] = False
try:
token = read_json(raw)['auth']['client_token']
require(isinstance(token, str) and token, 'late_session_response_invalid')
except (KeyError, TypeError, ValueError, Refused):
self.receipt['openbao_login_outcome_unknown'] = True
return
begin_cleanup()
self.receipt['late_acceptance_revoke_attempted'] = True
try:
status, _ = self.post(self.bao_origin + '/v1/auth/token/revoke-self',
body={}, headers={'X-Vault-Token': token})
self.receipt['late_acceptance_revoke_succeeded'] = status == 204
except Exception:
self.receipt['late_acceptance_revoke_succeeded'] = False
finally:
del token
def post(self, url, form=None, body=None, headers=None, timeout=15):
headers = dict(headers or {})
if form is not None:
data = urllib.parse.urlencode(form).encode()
headers['Content-Type'] = 'application/x-www-form-urlencoded'
else:
data = json.dumps(body or {}).encode()
headers['Content-Type'] = 'application/json'
return self.request(url, data=data, headers=headers, timeout=timeout)
def health_identity(self):
# Public endpoint only: no token/header, login, Secret or route creation.
status, raw = self.request(self.bao_origin + '/v1/sys/health', method='GET')
require(status == 200, 'bao_public_health_unavailable')
try:
body = read_json(raw)
require(isinstance(body, dict) and body.get('initialized') is True
and body.get('sealed') is False and body.get('standby') is False
and body.get('performance_standby', False) is False,
'bao_public_health_not_active')
cluster_id = body.get('cluster_id')
require(isinstance(cluster_id, str) and 0 < len(cluster_id) <= 128,
'bao_public_health_identity_required')
return digest(cluster_id.encode())
except (TypeError, ValueError):
raise Refused('bao_public_health_invalid') from None
def discovery(self):
status, raw = self.request('https://kc.coulomb.social/.well-known/openid-configuration', method='GET')
require(status == 200, 'discovery_failed')
return json.loads(raw)
def k(arguments, payload=None):
# Execute on railiance01 in the founder's session, never workstation defaults.
check_deadline()
budget = request_budget(30)
with total_timeout(budget):
result = subprocess.run(['kubectl', '--kubeconfig=/etc/rancher/k3s/k3s.yaml',
'--request-timeout=20s', *arguments],
input=None if payload is None else json.dumps(payload),
text=True, capture_output=True, timeout=budget)
check_deadline()
require(result.returncode == 0, 'kubernetes_operation_failed')
return json.loads(result.stdout) if result.stdout.strip() else None
def get(kind, name):
return k(['-n', 'sso', 'get', kind, name, '-o', 'json'])
def meta(obj):
return {key: obj['metadata'][key] for key in ['uid', 'resourceVersion']}
def patch(kind, obj, path, value, dry=False):
ops = [{'op': 'test', 'path': '/metadata/' + key, 'value': val}
for key, val in meta(obj).items()]
ops.append({'op': 'replace', 'path': path, 'value': value})
args = ['-n', 'sso', 'patch', kind, obj['metadata']['name'], '--type=json',
'--patch-file=/dev/stdin', '-o', 'json']
if dry:
args += ['--dry-run=server']
return k(args, ops)
def registrations():
reference = {'displayName': 'Temporary KEY39 negative probe',
'allowedScopes': ['openbao:login'], 'grantTypes': ['client_credentials'],
'clientType': 'confidential', 'serviceSubject': 'service:secrets-engine',
'tenant': 'tenant:platform', 'roles': ['secrets-engine'], 'tokenLifetime': '1m'}
result = []
for index, client_id in enumerate(IDS):
c = dict(reference, clientId=client_id, secretRef='env:' + ENVS[index])
if index:
c['audience'] = 'secrets-engine-openbao'
if index == 1:
c['serviceSubject'] = 'service:openbao-probe'
if index == 2:
c['tenant'] = 'tenant:openbao-probe'
if index == 3:
c['roles'] = ['openbao-probe']
if index == 4:
c['allowedScopes'] = ['openbao:probe']
result.append(c)
return result
class UniqueLoader(yaml.SafeLoader):
pass
def unique(loader, node):
result = {}
for key_node, value_node in node.value:
key = loader.construct_object(key_node)
require(key not in result, 'duplicate_yaml_key')
result[key] = loader.construct_object(value_node)
return result
UniqueLoader.add_constructor(yaml.resolver.BaseResolver.DEFAULT_MAPPING_TAG, unique)
def candidate_config(raw):
config = yaml.load(raw, Loader=UniqueLoader)
clients = config['clients']
require(isinstance(clients, list) and clients, 'clients_required')
ids = [c['clientId'] for c in clients]
require(len(ids) == len(set(ids)) and not set(ids).intersection(IDS), 'existing_probe_or_duplicate')
require(not {c.get('secretRef') for c in clients}.intersection('env:' + e for e in ENVS),
'probe_secretref_collision')
production = [c for c in clients if c['clientId'] == 'secrets-engine-openbao']
require(len(production) == 1, 'production_client_missing')
expected = registrations()[-1]
for field in ['allowedScopes', 'grantTypes', 'clientType', 'serviceSubject', 'tenant', 'roles']:
require(production[0].get(field) == expected[field], 'production_claim_contract_drift')
require(production[0].get('audience', production[0]['clientId']) == 'secrets-engine-openbao',
'production_audience_drift')
nodes = yaml.compose(raw)
node = next(v for key, v in nodes.value if key.value == 'clients')
require(isinstance(node, yaml.nodes.SequenceNode) and not node.flow_style,
'block_client_sequence_required')
index = node.end_mark.index
start = raw.rfind('\n', 0, index) + 1
if not raw[start:index].strip():
index = start
fragment = yaml.safe_dump(registrations(), sort_keys=False)
fragment = ''.join(' ' * node.start_mark.column + line if line.strip() else line
for line in fragment.splitlines(True))
if index and raw[index - 1] != '\n':
fragment = '\n' + fragment
updated = raw[:index] + fragment + raw[index:]
intended = copy.deepcopy(config)
intended['clients'].extend(registrations())
require(yaml.load(updated, Loader=UniqueLoader) == intended, 'unrelated_config_changed')
return updated
def candidate_spec(spec):
result = copy.deepcopy(spec)
require(result.get('replicas', 1) == 1 and result['strategy']['type'] == 'Recreate',
'single_replica_recreate_required')
container = next(c for c in result['template']['spec']['containers'] if c['name'] == 'keycape')
env = container['env']
require(not {e['name'] for e in env}.intersection(ENVS), 'probe_env_collision')
env.extend({'name': e, 'valueFrom': {'secretKeyRef': {'name': TEMP, 'key': c}}}
for c, e in zip(IDS, ENVS))
return result
def ready(spec, timeout=150):
deadline = time.monotonic() + timeout
while time.monotonic() < deadline:
dep = get('deployment', 'keycape')
require(dep['spec'] == spec, 'deployment_drift_during_readiness')
status = dep.get('status', {})
if (status.get('observedGeneration') == dep['metadata']['generation']
and all(status.get(key) == 1 for key in
['updatedReplicas', 'readyReplicas', 'availableReplicas', 'replicas'])):
return True
time.sleep(3)
raise Refused('readiness_timeout')
def verify_sources(envelope, recovery=False):
require(envelope.get('proposal_id') == PROPOSAL and envelope.get('target') == TARGET,
'proposal_target_mismatch')
require(envelope.get('disposition') == ('recovery-approved' if recovery else 'approved')
and envelope.get('founder_decision_id'),
'founder_exact_go_required')
require(envelope.get('source_hashes') and
str(Path(__file__).resolve()) in envelope['source_hashes'], 'executor_pin_required')
for filename, expected in envelope['source_hashes'].items():
require(digest(Path(filename).read_bytes()) == expected, 'reviewed_source_changed')
required = ['net-kingdom', 'key-cape', 'railiance-platform']
require(all(envelope.get('owner_acknowledgments', {}).get(owner) for owner in required),
'owner_acknowledgments_required')
expiry = envelope['valid_until_epoch']
maximum = envelope['maximum_session_seconds']
require(finite_number(expiry) and type(maximum) is int and
420 <= maximum <= 900 and 0 < expiry - time.time() <= maximum,
'attended_window_invalid')
if recovery:
return None
role = envelope['role_observation']
require(role['mount'] == 'keycape-services' and role['role'] == 'secrets-engine-openbao'
and role['issuer'] == 'https://kc.coulomb.social' and role['algorithm'] == 'RS256'
and role['bindings_exact'] is True and role['policy_exact'] is True,
'role_owner_observation_required')
leeway = role['raw_expiration_leeway']
require(type(leeway) is int and -1 <= leeway <= 150, 'leeway_outside_session_bound')
effective = 0 if leeway == -1 else leeway or 150
require(role['effective_expiration_leeway'] == effective, 'leeway_normalization_mismatch')
observed = role['observed_at_epoch']
require(finite_number(observed) and 0 <= time.time() - observed <= 300,
'role_observation_stale_or_future')
require(envelope['bao_addr'] in BAO_ORIGINS, 'bao_origin_invalid')
return effective
def load_probe(path):
spec = importlib.util.spec_from_file_location('key39_reviewed_probe', path)
result = importlib.util.module_from_spec(spec)
spec.loader.exec_module(result)
return result
def removed_client_denied(status, raw):
try:
body = json.loads(raw)
return status == 401 and body.get('error') == 'invalid_profile_usage' and body.get('feature') == 'client_id'
except (ValueError, AttributeError, TypeError):
return False
def recovered_config(raw):
config = yaml.load(raw, Loader=UniqueLoader)
clients = config['clients']
ids = [c['clientId'] for c in clients]
present = set(ids).intersection(IDS)
require(len(ids) == len(set(ids)) and present in [set(), set(IDS)], 'partial_probe_registry')
if not present:
return raw
require(clients[-6:] == registrations(), 'recovery_registration_drift')
node = next(v for key, v in yaml.compose(raw).value if key.value == 'clients')
first = node.value[-6].start_mark.index
start = raw.rfind('\n', 0, first) + 1
end = node.end_mark.index
line_start = raw.rfind('\n', 0, end) + 1
if not raw[line_start:end].strip():
end = line_start
restored = raw[:start] + raw[end:]
require(candidate_config(restored) == raw, 'recovery_byte_roundtrip_failed')
return restored
def recovered_spec(spec):
restored = copy.deepcopy(spec)
container = next(c for c in restored['template']['spec']['containers'] if c['name'] == 'keycape')
env = container['env']
expected = [{'name': e, 'valueFrom': {'secretKeyRef': {'name': TEMP, 'key': c}}}
for c, e in zip(IDS, ENVS)]
matches = [e for e in env if e['name'] in ENVS]
require(matches in [[], expected], 'partial_or_drifted_probe_env')
container['env'] = [e for e in env if e['name'] not in ENVS]
return restored
def delete_temporary(created):
# The exact raw API delete needs the same aggregate/per-request guards as patches.
k(['delete', '--raw=/api/v1/namespaces/sso/secrets/' + TEMP, '-f', '/dev/stdin'],
{'apiVersion': 'v1', 'kind': 'DeleteOptions', 'preconditions': meta(created)})
require(k(['-n', 'sso', 'get', 'secret', TEMP, '--ignore-not-found', '-o', 'json']) is None,
'temporary_secret_still_present')
def verify_bao_route(transport, envelope, receipt):
expected = envelope.get('bao_health_identity_sha256')
require(isinstance(expected, str) and len(expected) == 64
and all(c in '0123456789abcdef' for c in expected),
'approved_bao_health_identity_required')
require(transport.health_identity() == expected, 'bao_public_health_identity_changed')
receipt['bao_public_route_verified'] = True
def recover(envelope, receipt):
global REQUEST_DEADLINE, BUSINESS_MONOTONIC_DEADLINE, CLEANUP_MONOTONIC_DEADLINE, CLEANING
verify_sources(envelope, recovery=True)
# Separately approved recovery obligations are cleanup, never business writes.
REQUEST_DEADLINE = None
BUSINESS_MONOTONIC_DEADLINE = None
CLEANUP_MONOTONIC_DEADLINE = None
begin_cleanup()
CLEANING = True
transport = SessionTransport(envelope['bao_addr'], receipt=receipt)
verify_bao_route(transport, envelope, receipt)
require(k(['get', 'namespace', 'kube-system', '-o', 'json'])['metadata']['uid'] == CLUSTER,
'cluster_identity_changed')
config = get('secret', 'keycape-config')
dep = get('deployment', 'keycape')
raw = base64.b64decode(config['data']['config.yaml'], validate=True).decode()
restored = recovered_config(raw)
spec = recovered_spec(dep['spec'])
require(config['metadata']['uid'] == envelope['config_metadata']['uid']
and dep['metadata']['uid'] == envelope['deployment_metadata']['uid']
and digest(restored.encode()) == envelope['registry_sha256']
and canonical(spec) == envelope['deployment_spec_sha256'], 'recovery_baseline_drift')
temp = get('secret', TEMP)
require(set(temp.get('data', {})) == set(IDS)
and temp['metadata']['uid'] == envelope['temporary_secret_uid'], 'recovery_custody_identity_required')
values = {c: base64.b64decode(temp['data'][c], validate=True).decode() for c in IDS}
if raw != restored:
patch('secret', config, '/data/config.yaml', base64.b64encode(restored.encode()).decode())
if dep['spec'] != spec:
patch('deployment', dep, '/spec', spec)
ready(spec)
after = get('secret', 'keycape-config')
require(after['data'] == dict(config['data'], **{'config.yaml': base64.b64encode(restored.encode()).decode()}),
'recovery_readback_failed')
require(envelope['runner_path'] in envelope['source_hashes'], 'runner_pin_required')
probe = load_probe(envelope['runner_path'])
for client, value in values.items():
basic = base64.b64encode((client + ':' + value).encode()).decode()
status, body = transport.post('https://kc.coulomb.social/token',
form={'grant_type': 'client_credentials', 'scope': 'openbao:login'},
headers={'Authorization': 'Basic ' + basic})
require(removed_client_denied(status, body), 'removed_client_denial_unconfirmed')
observed = get('secret', TEMP)
require(observed['data'] == temp['data'] and observed['metadata']['uid'] == temp['metadata']['uid'],
'recovery_temporary_secret_drift')
delete_temporary(observed)
receipt.update(cleanup_verified=True, recovery_only=True)
def emit_private_ready(fd, nonce, expected_envelope_sha256, envelope_sha256, envelope, receipt):
# A value-free synchronization marker, never authentication or a grant.
require(type(fd) is int and fd >= 3, 'private_ready_pipe_required')
require(isinstance(nonce, str) and len(nonce) == 64
and all(c in '0123456789abcdef' for c in nonce), 'ready_nonce_required')
require(expected_envelope_sha256 == envelope_sha256, 'ready_envelope_pin_changed')
validated = False
try:
current = os.fstat(fd)
require(stat.S_ISFIFO(current.st_mode)
and fcntl.fcntl(fd, fcntl.F_GETFL) & os.O_ACCMODE == os.O_WRONLY,
'private_ready_pipe_required')
identity = (current.st_dev, current.st_ino)
require(all(identity != (os.fstat(other).st_dev, os.fstat(other).st_ino)
for other in (0, 1, 2)), 'private_ready_stdio_alias_refused')
validated = True
check_deadline()
marker = {'schema': READY_SCHEMA, 'session_nonce': nonce,
'proposal_id': PROPOSAL, 'target': TARGET,
'executor_sha256': digest(Path(__file__).read_bytes()),
'envelope_sha256': envelope_sha256,
'bao_health_identity_sha256': envelope['bao_health_identity_sha256'],
'valid_until_epoch': envelope['valid_until_epoch'],
'receive_budget_seconds': request_budget(PRIVATE_INPUT_TOTAL_SECONDS)}
payload = json.dumps(marker, sort_keys=True, separators=(',', ':')).encode() + b'\n'
require(len(payload) <= READY_MAX_BYTES, 'private_ready_oversized')
with total_timeout(request_budget(2)):
offset = 0
while offset < len(payload):
written = os.write(fd, payload[offset:])
require(type(written) is int and written > 0, 'private_ready_delivery_failed')
offset += written
check_deadline()
receipt['private_ready_emitted'] = True
except Refused:
raise
except Exception:
raise Refused('private_ready_delivery_failed') from None
finally:
if validated:
os.close(fd)
def read_private_input(stream):
# Complete private JSON plus EOF, within this original approved action window.
# No unbounded read, text buffering, token logging or renewed deadline.
check_deadline()
budget = request_budget(PRIVATE_INPUT_TOTAL_SECONDS)
binary = getattr(stream, 'buffer', None)
require(binary is not None, 'private_binary_input_required')
chunks, size = [], 0
with total_timeout(budget):
while True:
chunk = binary.read(min(4096, PRIVATE_INPUT_MAX_BYTES + 1 - size))
require(isinstance(chunk, bytes), 'private_binary_input_required')
if not chunk:
break
size += len(chunk)
require(size <= PRIVATE_INPUT_MAX_BYTES, 'private_input_oversized')
chunks.append(chunk)
check_deadline()
require(size > 0, 'private_input_empty')
try:
private = read_json(b''.join(chunks))
require(isinstance(private, dict)
and set(private) == {'human_token', 'coding_agent_token'}
and all(isinstance(value, str) and
0 < len(value.encode('utf-8')) <= PRIVATE_TOKEN_MAX_BYTES
for value in private.values()), 'private_input_invalid')
except (TypeError, ValueError, UnicodeError, Refused):
raise Refused('private_input_invalid') from None
check_deadline()
return private
def start_execution_window(envelope):
global REQUEST_DEADLINE, BUSINESS_MONOTONIC_DEADLINE, CLEANUP_MONOTONIC_DEADLINE, CLEANING
REQUEST_DEADLINE = envelope['valid_until_epoch']
BUSINESS_MONOTONIC_DEADLINE = time.monotonic() + min(
REQUEST_DEADLINE - time.time(), envelope['maximum_session_seconds'] - 180)
CLEANUP_MONOTONIC_DEADLINE = None
CLEANING = False
def execute(envelope, private, receipt, checkpoint=lambda: None, window_started=False):
global CLEANING
leeway = verify_sources(envelope)
if not window_started:
start_execution_window(envelope)
else:
# main already began this exact window before consuming private stdin.
# Preserve its original monotonic budget; input waiting cannot renew it.
require(REQUEST_DEADLINE == envelope['valid_until_epoch']
and BUSINESS_MONOTONIC_DEADLINE is not None and not CLEANING,
'preinput_execution_window_required')
check_deadline()
runner_path = envelope['runner_path']
require(runner_path in envelope['source_hashes'], 'runner_pin_required')
probe = load_probe(runner_path)
transport = SessionTransport(envelope['bao_addr'], receipt=receipt)
discovery = transport.discovery()
require(discovery.get('issuer') == 'https://kc.coulomb.social' and
discovery.get('token_endpoint') == 'https://kc.coulomb.social/token',
'issuer_discovery_changed')
verify_bao_route(transport, envelope, receipt)
require(isinstance(private.get('human_token'), str) and private['human_token']
and isinstance(private.get('coding_agent_token'), str) and private['coding_agent_token'],
'founder_private_tokens_required')
require(k(['get', 'namespace', 'kube-system', '-o', 'json'])['metadata']['uid'] == CLUSTER,
'cluster_identity_changed')
before = get('secret', 'keycape-config')
deployment = get('deployment', 'keycape')
require(not before['metadata'].get('ownerReferences'), 'controller_owned_config')
require(meta(before) == envelope['config_metadata']
and meta(deployment) == envelope['deployment_metadata']
and canonical(deployment['spec']) == envelope['deployment_spec_sha256'],
'approved_runtime_revision_changed')
raw = base64.b64decode(before['data']['config.yaml'], validate=True).decode()
require(digest(raw.encode()) == envelope['registry_sha256'], 'approved_registry_changed')
updated = base64.b64encode(candidate_config(raw).encode()).decode()
intended_data = dict(before['data'], **{'config.yaml': updated})
candidate = candidate_spec(deployment['spec'])
ready(deployment['spec'])
# Exact GET existence is tested via create (never adopt/delete an existing Secret).
values = {c: secrets.token_urlsafe(48) for c in IDS}
temporary = {'apiVersion': 'v1', 'kind': 'Secret', 'metadata': {'namespace': 'sso', 'name': TEMP},
'type': 'Opaque', 'data': {c: base64.b64encode(v.encode()).decode() for c, v in values.items()}}
patch('secret', before, '/data/config.yaml', updated, dry=True)
patch('deployment', deployment, '/spec', candidate, dry=True)
k(['create', '-f', '/dev/stdin', '--dry-run=server', '-o', 'json'], temporary)
created = None
mutations_attempted = False
began = time.monotonic()
try:
# Set before API call: uncertain response must still trigger reconciliation.
check_deadline()
verify_bao_route(transport, envelope, receipt)
mutations_attempted = True
created = k(['create', '-f', '/dev/stdin', '-o', 'json'], temporary)
receipt['temporary_secret_uid'] = created['metadata']['uid']
checkpoint()
patch('secret', before, '/data/config.yaml', updated)
patch('deployment', deployment, '/spec', candidate)
ready(candidate)
require(get('secret', 'keycape-config')['data'] == intended_data, 'registry_drift')
require(time.monotonic() - began < 300, 'probe_start_too_late')
# Current admitted agent token stays founder-owned; no existing secret fetched.
original_exchange = probe.exchange
def exchange(post, endpoint, client, secret, scope):
if client == 'codex-railiance-platform':
return private['coding_agent_token']
return original_exchange(post, endpoint, client, secret, scope)
probe.exchange = exchange
supplied = dict(values, **{'codex-railiance-platform': 'founder-held-token'})
def bounded_post(*args, **kwargs):
if not args[0].endswith('/v1/auth/token/revoke-self'):
require(time.monotonic() - began < envelope['maximum_session_seconds'] - 180,
'session_cleanup_reserve_reached')
return transport.post(*args, **kwargs)
def bounded_sleep(seconds):
while seconds > 0:
check_deadline()
require(time.monotonic() - began < envelope['maximum_session_seconds'] - 180,
'session_cleanup_reserve_reached')
part = min(seconds, 3)
time.sleep(part)
seconds -= part
result = probe.run(bounded_post, supplied, 'https://kc.coulomb.social/token',
envelope['bao_addr'], 'keycape-services', 'secrets-engine-openbao',
human_token=private['human_token'], leeway=leeway, sleep=bounded_sleep)
receipt['negative_probe'] = result
checkpoint()
check_deadline()
require(time.monotonic() - began <= envelope['maximum_session_seconds'], 'session_window_exceeded')
require(result['all_refused'], 'negative_proof_incomplete')
finally:
if mutations_attempted:
begin_cleanup()
CLEANING = True
# Never restore over an unrelated edit; keep custody for owner recovery on drift.
now = get('secret', 'keycape-config')
require(now['metadata']['uid'] == before['metadata']['uid'] and
now['data'] in [before['data'], intended_data], 'cleanup_registry_drift')
if now['data'] == intended_data:
patch('secret', now, '/data/config.yaml', before['data']['config.yaml'])
now = get('deployment', 'keycape')
require(now['metadata']['uid'] == deployment['metadata']['uid'] and
now['spec'] in [deployment['spec'], candidate], 'cleanup_deployment_drift')
if now['spec'] == candidate:
patch('deployment', now, '/spec', deployment['spec'])
ready(deployment['spec'])
require(get('secret', 'keycape-config')['data'] == before['data'], 'cleanup_readback_failed')
# No fresh JWT is minted: deleted clients must fail at the issuer.
for client in IDS:
basic = base64.b64encode((client + ':' + values[client]).encode()).decode()
status, body = transport.post('https://kc.coulomb.social/token',
form={'grant_type': 'client_credentials', 'scope': 'openbao:login'},
headers={'Authorization': 'Basic ' + basic})
require(removed_client_denied(status, body),
'removed_client_denial_unconfirmed')
if created is None:
# A timed-out create may have succeeded; compare generated bytes before delete.
observed = get('secret', TEMP)
require(observed.get('data') == temporary['data'], 'temporary_secret_identity_unconfirmed')
created = observed
observed = get('secret', TEMP)
require(observed['metadata']['uid'] == created['metadata']['uid']
and observed.get('data') == temporary['data'], 'temporary_secret_drift')
delete_temporary(observed)
receipt['cleanup_verified'] = True
def main():
ap = argparse.ArgumentParser(description=__doc__.splitlines()[0])
ap.add_argument('mode', choices=['inspect', 'route-preflight', 'founder-preflight', 'execute', 'recover'])
ap.add_argument('--envelope')
ap.add_argument('--bao-addr', choices=sorted(BAO_ORIGINS))
ap.add_argument('--ready-fd', type=int)
ap.add_argument('--session-nonce')
ap.add_argument('--ready-envelope-sha256')
ap.add_argument('--confirm')
ap.add_argument('--receipt', required=True)
args = ap.parse_args()
receipt = {'proposal_id': PROPOSAL, 'target': TARGET, 'native_accepted': False,
'values_emitted': False, 'cleanup_verified': False}
# Do not truncate or follow a link; protected receipts cannot overwrite credentials.
fd = os.open(args.receipt, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)
def checkpoint():
os.lseek(fd, 0, os.SEEK_SET)
os.ftruncate(fd, 0)
os.write(fd, json.dumps(receipt, sort_keys=True, indent=2).encode())
os.fsync(fd)
rc = 1
try:
if args.mode == 'route-preflight':
require(args.bao_addr is not None, 'bao_origin_required')
transport = SessionTransport(args.bao_addr, receipt=receipt)
receipt.update(bao_health_identity_sha256=transport.health_identity(),
bao_public_route_verified=True, mode='public_route_preflight',
probe_location='current_process_only')
elif args.mode in ['inspect', 'founder-preflight']:
require(k(['get', 'namespace', 'kube-system', '-o', 'json'])['metadata']['uid'] == CLUSTER,
'cluster_identity_changed')
dep = get('deployment', 'keycape')
receipt.update(deployment_metadata=meta(dep), deployment_spec_sha256=canonical(dep['spec']),
image=next(c['image'] for c in dep['spec']['template']['spec']['containers']
if c['name'] == 'keycape'), mode='metadata_only')
if args.mode == 'founder-preflight':
require(args.confirm == 'FOUNDER ATTENDED KEY39 PREFLIGHT', 'founder_attendance_required')
require(args.bao_addr is not None, 'bao_origin_required')
transport = SessionTransport(args.bao_addr, receipt=receipt)
receipt.update(bao_health_identity_sha256=transport.health_identity(),
bao_public_route_verified=True)
config = get('secret', 'keycape-config')
require(not config['metadata'].get('ownerReferences'), 'controller_owned_config')
raw = base64.b64decode(config['data']['config.yaml'], validate=True).decode()
candidate_config(raw)
candidate_spec(dep['spec'])
require(k(['-n', 'sso', 'get', 'secret', TEMP, '--ignore-not-found', '-o', 'json']) is None,
'temporary_secret_already_exists')
ready(dep['spec'])
receipt.update(config_metadata=meta(config), registry_sha256=digest(raw.encode()),
baseline_ready=True, mode='founder_protected_preflight',
probe_ids_absent=True, probe_env_absent=True, temporary_secret_absent=True)
else:
require(args.envelope is not None, 'approval_envelope_required')
envelope_raw = Path(args.envelope).read_bytes()
envelope = read_json(envelope_raw)
envelope_sha256 = digest(envelope_raw)
require(Path(args.envelope).stat().st_mode & 0o022 == 0, 'approval_envelope_writable')
signal.signal(signal.SIGTERM, lambda *_: (_ for _ in ()).throw(Refused('session_interrupted')))
if args.mode == 'recover':
recover(envelope, receipt)
else:
# Public route/source readiness precedes private token consumption.
verify_sources(envelope)
start_execution_window(envelope)
transport = SessionTransport(envelope['bao_addr'], receipt=receipt)
verify_bao_route(transport, envelope, receipt)
emit_private_ready(args.ready_fd, args.session_nonce, args.ready_envelope_sha256,
envelope_sha256, envelope, receipt)
private = read_private_input(__import__('sys').stdin)
execute(envelope, private, receipt, checkpoint=checkpoint, window_started=True)
receipt['negative_and_cleanup_verified'] = True
rc = 0
except Refused as error:
receipt.update(status='incomplete_requires_owner_review', reason=str(error))
except BaseException:
# Fixed outcome only: exception text may contain protected Kubernetes/HTTP data.
receipt['status'] = 'incomplete_requires_owner_review'
finally:
checkpoint()
os.close(fd)
return rc
if __name__ == '__main__':
raise SystemExit(main())