the-custodian/docs/changes/netkingdom-target-2026-10-18/keycape-token-status-r1/binary_fixture.py
codex 90e29dccfc
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Reject generated-only commits / generated-commit-guard (push) Successful in 10s
Verify issuer-owned current token status and scoped revocation source
2026-10-18 10:21:40 +02:00

153 lines
7.2 KiB
Python

"""Exercise the built server in the runner's private network with synthetic input."""
import base64
import hashlib
import http.client
import json
import os
from pathlib import Path
import secrets
import socket
import subprocess
import tempfile
import time
import urllib.parse
workspace = Path('/work')
binary = workspace / 'keycape-candidate'
assert binary.is_file()
private = Path(tempfile.mkdtemp(prefix='token-status-private-'))
key = private / 'issuer.pem'
with key.open('xb') as output:
os.chmod(key, 0o600)
subprocess.run(['openssl', 'genpkey', '-algorithm', 'RSA', '-pkeyopt', 'rsa_keygen_bits:2048'],
stdout=output, stderr=subprocess.DEVNULL, check=True)
secret = secrets.token_urlsafe(24)
with socket.socket() as listener:
listener.bind(('127.0.0.1', 0))
port = listener.getsockname()[1]
cfg = {'issuer': 'https://issuer.fixture.invalid', 'port': port, 'tokenLifetime': '15m',
'privateKeyPem': str(key), 'environment': 'dev', 'tokenStatus': {'enabled': True, 'maxEntries': 2},
'clients': [{'clientId': 'fixture-client', 'clientType': 'confidential',
'grantTypes': ['client_credentials'], 'allowedScopes': ['fixture.read'],
'secretRef': 'env:FIXTURE_ONLY_CLIENT_SECRET', 'serviceSubject': 'service:fixture',
'tenant': 'tenant:fixture', 'audience': 'resource:fixture', 'tokenLifetime': '1m'}]}
config = private / 'config.json'
config.write_text(json.dumps(cfg))
os.chmod(config, 0o600)
auth = 'Basic ' + base64.b64encode(('fixture-client:' + urllib.parse.quote_plus(secret)).encode()).decode()
tokens, checks, logs, processes = [], [], [], []
def request(path, form=None, authenticated=True):
conn = http.client.HTTPConnection('127.0.0.1', port, timeout=3)
headers = {}
if authenticated:
headers['Authorization'] = auth
body = None if form is None else urllib.parse.urlencode(form)
if body is not None:
headers['Content-Type'] = 'application/x-www-form-urlencoded'
try:
conn.request('GET' if form is None else 'POST', path, body, headers)
response = conn.getresponse()
return response.status, dict(response.getheaders()), response.read(65537)
finally:
conn.close()
def check(label, condition):
checks.append({'check': label, 'passed': bool(condition)})
if not condition:
raise AssertionError(label)
def start(label):
log = private / (label + '.log')
output = log.open('xb')
process = subprocess.Popen([str(binary), '--config', str(config)], stdout=output, stderr=subprocess.STDOUT,
env={**os.environ, 'FIXTURE_ONLY_CLIENT_SECRET': secret})
output.close()
logs.append(log)
processes.append(process)
for _ in range(100):
if process.poll() is not None:
raise AssertionError('fixture process exited before readiness')
try:
if request('/healthz', authenticated=False)[0] == 200:
return process
except OSError:
pass
time.sleep(0.02)
raise AssertionError('fixture startup timed out')
def stop(process):
process.terminate()
try:
process.wait(timeout=5)
except subprocess.TimeoutExpired:
process.kill()
process.wait(timeout=3)
raise AssertionError('fixture required forced termination')
check('graceful_process_exit', process.returncode == 0)
def issue():
status, _, body = request('/token', {'grant_type': 'client_credentials'})
if status != 200:
return status, None
token = json.loads(body)['access_token']
tokens.append(token)
return status, token
def introspect(raw):
status, headers, body = request('/introspect', {'token': raw})
check('introspection_private_cache_control', headers.get('Cache-Control') == 'no-store')
return status, json.loads(body)
report = {'binary_sha256': 'sha256:' + hashlib.sha256(binary.read_bytes()).hexdigest(),
'checks': checks, 'real_credentials': False, 'native_acceptance': False,
'transport': 'isolated fixture HTTP backend; separate handler test proves fixture HTTPS',
'source': 'standalone built KeyCape executable with actual main router/config/grants/store'}
try:
process = start('enabled')
status, _, body = request('/.well-known/openid-configuration', authenticated=False)
discovery = json.loads(body)
check('enabled_discovery', status == 200 and discovery['introspection_endpoint'].endswith('/introspect') and discovery['revocation_endpoint'].endswith('/revoke'))
status, first = issue()
check('actual_service_grant', status == 200 and bool(first))
status, second = issue()
check('distinct_service_grants', status == 200 and first != second)
status, metadata = introspect(first)
check('current_service_metadata', status == 200 and metadata.get('active') is True and metadata.get('aud') == 'resource:fixture' and metadata.get('client_id') == 'fixture-client')
check('capacity_refuses_without_token', issue() == (503, None))
status, _, body = request('/revoke', {'token': first})
check('actual_revocation', status == 200 and body == b'')
check('revoked_token_inactive', introspect(first)[1] == {'active': False})
check('other_grant_still_active', introspect(second)[1].get('active') is True)
check('tombstone_not_evicted', issue() == (503, None))
check('unauthenticated_introspection_refused', request('/introspect', {'token': second}, authenticated=False)[0] == 401)
stop(process)
process = start('restarted')
check('actual_process_restart_refuses_predecessor', introspect(second)[1] == {'active': False})
status, third = issue()
check('fresh_post_restart_grant', status == 200 and third not in (first, second) and introspect(third)[1].get('active') is True)
check('new_grant_does_not_resurrect_predecessor', introspect(first)[1] == {'active': False})
stop(process)
cfg['tokenStatus'] = {'enabled': False}
config.write_text(json.dumps(cfg))
process = start('legacy')
_, _, body = request('/.well-known/openid-configuration', authenticated=False)
discovery = json.loads(body)
check('disabled_discovery_omits_endpoints', 'introspection_endpoint' not in discovery and 'revocation_endpoint' not in discovery)
check('disabled_router_has_no_endpoint', request('/introspect', {'token': second})[0] == 404)
status, fourth = issue()
payload = fourth.split('.')[1]
claims = json.loads(base64.urlsafe_b64decode(payload + '=' * (-len(payload) % 4)))
check('legacy_service_grant_has_no_new_claim', status == 200 and 'jti' not in claims)
stop(process)
combined = b''.join(path.read_bytes() for path in logs)
needles = [secret.encode(), key.read_bytes(), *(token.encode() for token in tokens)]
check('actual_process_diagnostics_omit_private_material', all(value not in combined for value in needles))
report['status'] = 'passed'
finally:
for process in processes:
if process.poll() is None:
stop(process)
report['all_owned_processes_terminal'] = all(p.poll() is not None for p in processes)
(workspace / 'binary-fixture-receipt.json').write_text(json.dumps(report, indent=2) + '\n')
print(json.dumps({'status': report['status'], 'checks': len(checks), 'all_owned_processes_terminal': report['all_owned_processes_terminal']}))