the-custodian/docs/evidence/2026-10-10-security-consolidation/submit-security-decisions.py
codex 9ea453708f
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Record accepted security collaboration and verified scoped native rollout
2026-10-11 03:09:50 +02:00

65 lines
3.3 KiB
Python

"""Run inside the already admitted State Hub dispatcher; no token leaves it."""
import json
import re
import sys
import urllib.request
import urllib.error
from api.services.memo_dispatch import Dispatcher, ORIGIN, NoRedirect, token_file
commands = json.loads(sys.stdin.read(256 * 1024))
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}), NoRedirect())
token_path = '/var/run/secrets/state-hub/informed-decision/lifecycle-token'
def call(method, path, body=None, key=None):
if not path.startswith('/v1/decisions'):
raise ValueError('route_refused')
raw = json.dumps(body).encode() if body is not None else None
if raw is not None and len(raw) > 256 * 1024:
raise ValueError('input_too_large')
headers = {'Authorization': 'Bearer ' + token_file(token_path),
'Content-Type': 'application/json'}
if key:
headers['Idempotency-Key'] = key
req = urllib.request.Request(ORIGIN + path, data=raw, headers=headers, method=method)
try:
response = opener.open(req, timeout=15)
except urllib.error.HTTPError as error:
response = error
with response:
result = response.read(1024 * 1024 + 1)
if len(result) > 1024 * 1024:
raise ValueError('response_unavailable')
value = json.loads(result)
if response.code not in (200, 201):
code = value.get('error', 'request_refused') if isinstance(value, dict) else 'request_refused'
code = code if isinstance(code, str) and re.fullmatch('[a-z0-9_]{1,64}', code) else 'request_refused'
print(json.dumps({'http_status': response.code, 'error': code}), flush=True)
raise ValueError('operation_refused')
return value
for command in commands:
ident = command['id']
if not re.fullmatch('[a-z0-9-]{3,63}', ident):
raise SystemExit('invalid_memo_identity')
try:
receipts = {}
for action, path in [('register', '/v1/decisions'),
('publish', '/v1/decisions/' + ident + '/publications'),
('review', '/v1/decisions/' + ident + '/review-requests')]:
receipts[action] = call('POST', path, command[action],
'security-consolidation.' + ident + '.' + action + '.v1')
handoff = receipts['review']
queued = Dispatcher('/data/private').enqueue(handoff['envelope'])
outcome = call('GET', '/v1/decisions/' + ident + '/outcomes?version=1')
print(json.dumps({'memo_id': ident, 'version': 1,
'register_event_id': receipts['register']['event_id'],
'publication_event_id': receipts['publish']['event_id'],
'review_event_id': handoff['event_id'],
'review_memo_id': handoff['review_memo_id'],
'queue_status': queued.status, 'queue_detail': queued.detail,
'workspace_url': 'https://decisions.coulomb.social/decisions/' + ident + '?version=1',
'outcome_review': outcome.get('review'),
'human_dispositions': len(outcome.get('dispositions', []))}), flush=True)
except Exception:
print(json.dumps({'memo_id': ident, 'status': 'operation_unverified'}), flush=True)
raise SystemExit(1) from None