107 lines
4.9 KiB
Python
107 lines
4.9 KiB
Python
|
|
"""Silent bounded CCR-2026-0019 acceptance; never creates or consumes approvals."""
|
||
|
|
import json
|
||
|
|
import os
|
||
|
|
from pathlib import Path
|
||
|
|
import signal
|
||
|
|
import stat
|
||
|
|
import tempfile
|
||
|
|
from datetime import datetime, timezone
|
||
|
|
from urllib.request import Request, build_opener, ProxyHandler, HTTPRedirectHandler
|
||
|
|
from urllib.error import HTTPError
|
||
|
|
from uuid import uuid4
|
||
|
|
|
||
|
|
import importlib.util
|
||
|
|
_spec = importlib.util.spec_from_file_location('reader_preflight', Path(__file__).with_name('approval-client-reader-preflight.py'))
|
||
|
|
preflight = importlib.util.module_from_spec(_spec)
|
||
|
|
_spec.loader.exec_module(preflight)
|
||
|
|
|
||
|
|
RECEIPT = Path('/home/worsch/railiance-platform/docs/evidence/2026-09-14-ccr0019-delivery-check.json')
|
||
|
|
class NoRedirect(HTTPRedirectHandler):
|
||
|
|
def redirect_request(self, *args, **kwargs):
|
||
|
|
return None
|
||
|
|
|
||
|
|
def transport(request, *, timeout):
|
||
|
|
return build_opener(ProxyHandler({}), NoRedirect()).open(request, timeout=timeout)
|
||
|
|
|
||
|
|
def private(path, mode, directory=False):
|
||
|
|
info = path.lstat()
|
||
|
|
if stat.S_IMODE(info.st_mode) != mode or info.st_uid != os.getuid():
|
||
|
|
raise ValueError('private_path_required')
|
||
|
|
if not (stat.S_ISDIR(info.st_mode) if directory else stat.S_ISREG(info.st_mode)):
|
||
|
|
raise ValueError('private_path_required')
|
||
|
|
|
||
|
|
def main():
|
||
|
|
receipt = {'observed_at':datetime.now(timezone.utc).isoformat(), 'ccr_id':'CCR-2026-0019',
|
||
|
|
'status':'refused', 'approval_mutations':False, 'checks':{}, 'cleanup':False}
|
||
|
|
directory = None
|
||
|
|
secret_file = None
|
||
|
|
try:
|
||
|
|
preflight.main()
|
||
|
|
from secrets_engine.approval_auth import KeyCapeApprovalAuthConfig
|
||
|
|
from secrets_engine.service_auth import KeyCapeServiceAuthProvider
|
||
|
|
runtime = Path('/run/user') / str(os.getuid())
|
||
|
|
private(runtime, 0o700, True)
|
||
|
|
if runtime.resolve() != runtime:
|
||
|
|
raise ValueError('private_path_required')
|
||
|
|
result = preflight.subprocess.run(['findmnt','-n','-o','FSTYPE','-T',str(runtime)],capture_output=True,text=True,timeout=10)
|
||
|
|
if result.returncode or result.stdout.strip() != 'tmpfs':
|
||
|
|
raise ValueError('runtime_tmpfs_required')
|
||
|
|
directory = Path(tempfile.mkdtemp(prefix='secrets-approval-',dir=runtime))
|
||
|
|
private(directory, 0o700, True)
|
||
|
|
secret_file = directory/'client-secret'
|
||
|
|
helper = Path.home()/'.vault-token'
|
||
|
|
private(helper, 0o600)
|
||
|
|
token = helper.read_text().strip()
|
||
|
|
req = Request('https://bao.coulomb.social/v1/platform/data/workloads/secrets-engine/approval-client?version=1',headers={'X-Vault-Token':token})
|
||
|
|
with transport(req,timeout=20) as response:
|
||
|
|
data = response.read(65537)
|
||
|
|
if len(data)>65536:
|
||
|
|
raise ValueError('custody_response_invalid')
|
||
|
|
data=json.loads(data)
|
||
|
|
if data['data']['metadata']['version'] != 1:
|
||
|
|
raise ValueError('custody_response_invalid')
|
||
|
|
value=data['data']['data']['CLIENT_SECRET']
|
||
|
|
if not isinstance(value,str) or not value or len(value)>16384:
|
||
|
|
raise ValueError('custody_response_invalid')
|
||
|
|
fd=os.open(secret_file,os.O_WRONLY|os.O_CREAT|os.O_EXCL|os.O_NOFOLLOW,0o600)
|
||
|
|
with os.fdopen(fd,'w') as stream:
|
||
|
|
stream.write(value)
|
||
|
|
del value, data, token, req
|
||
|
|
private(secret_file,0o600)
|
||
|
|
receipt['checks']['private_delivery_existing_version_1']=True
|
||
|
|
approval_id=str(uuid4())
|
||
|
|
for scope in ('approval:read','approval:consume'):
|
||
|
|
config=KeyCapeApprovalAuthConfig(token_url='https://kc.coulomb.social/token',issuer='https://kc.coulomb.social',client_secret_file=secret_file,scope=scope)
|
||
|
|
jwt=KeyCapeServiceAuthProvider(config,transport=transport).exchange()
|
||
|
|
request=Request('http://127.0.0.1:18281/v1/approvals/'+approval_id+'/claim',headers={'Authorization':'Bearer '+jwt.token})
|
||
|
|
try:
|
||
|
|
with transport(request,timeout=20) as response:
|
||
|
|
status=response.status
|
||
|
|
except HTTPError as error:
|
||
|
|
status=error.code
|
||
|
|
error.close()
|
||
|
|
expected=404 if scope=='approval:read' else 403
|
||
|
|
if status != expected:
|
||
|
|
raise ValueError('native_scope_check_failed')
|
||
|
|
receipt['checks'][scope]={'native_claim_http_status':status,'profile_checked':True}
|
||
|
|
del jwt, request
|
||
|
|
receipt['status']='passed'
|
||
|
|
except Exception:
|
||
|
|
receipt['failure']='delivery_check_failed'
|
||
|
|
raise
|
||
|
|
finally:
|
||
|
|
if secret_file is not None and secret_file.exists():
|
||
|
|
secret_file.unlink()
|
||
|
|
if directory is not None:
|
||
|
|
directory.rmdir()
|
||
|
|
receipt['cleanup']=directory is None or not directory.exists()
|
||
|
|
RECEIPT.write_text(json.dumps(receipt,indent=2)+'\n')
|
||
|
|
|
||
|
|
if __name__=='__main__':
|
||
|
|
for sig in (signal.SIGINT,signal.SIGTERM):
|
||
|
|
signal.signal(sig,lambda *_: (_ for _ in ()).throw(SystemExit(130)))
|
||
|
|
try:
|
||
|
|
main()
|
||
|
|
except Exception:
|
||
|
|
raise SystemExit(1) from None
|