"""Founder-run read-only scanner preflight; prints only selected public evidence.""" import subprocess,json,hashlib,pathlib,sys NS='forgejo';NAME='forge';POD='forge-79c7fb84db-k5wtm' EXPECTED_UID='1faefb26-cccd-4d0e-b509-70a7eb0b4f4d' POD_UID='2c9f911a-403e-4183-a027-2b8d48742348' BASE='/data/security/receive-secret-scan/20261027-b735d052a49f' ADAPTER='b735d052a49fc8e9cca14cddee074c5429352ad71841eb6548459294f15683a2' SCANNER='88f91962aa2f93ac6ab281d553b9e125f5197bbbce38f9f2437f7299c32e5509' def k(*args): q=subprocess.run(['kubectl',*args],capture_output=True,timeout=60) if q.returncode:raise RuntimeError('read-only-command-failed; raw diagnostics withheld') return q.stdout def main(): d=json.loads(k('-n',NS,'get','deployment',NAME,'-o','json')) if d['metadata']['uid']!=EXPECTED_UID:raise RuntimeError('deployment-identity-drift') uid=k('-n',NS,'get','pod',POD,'-o','jsonpath={.metadata.uid}').decode() if uid!=POD_UID:raise RuntimeError('pod-identity-drift') spec=d['spec']['template']['spec'];inits=spec.get('initContainers',[]) candidates=[c['name'] for c in spec['containers'] if c.get('image')=='code.forgejo.org/forgejo/forgejo:11.0.3-rootless'] if len(candidates)!=1:raise RuntimeError('forge-container-ambiguous') container=candidates[0] guards=[(i,x) for i,x in enumerate(inits) if x['name']=='verify-secret-scanner'] if len(guards)!=1:raise RuntimeError('scanner-guard-ambiguous') index,guard=guards[0] volumes=spec.get('volumes',[]);selected=[(i,x) for i,x in enumerate(volumes) if x['name']=='secret-scan-template'] if len(selected)!=1:raise RuntimeError('scanner-volume-ambiguous') vindex,volume=selected[0];cmname=volume['configMap']['name'] if cmname!='forgejo-secret-template-d1df801be39f':raise RuntimeError('template-configmap-drift') # This exact public ConfigMap contains only the receiver hook, per owner source. hook=k('-n',NS,'get','configmap',cmname,'-o','jsonpath={.data.hook}') expected=('#!/bin/sh\nset +vx\nset -eu\nexec '+BASE+'/receive-secret-scan --scanner '+BASE+'/gitleaks\n').encode() if hook!=expected:raise RuntimeError('mounted-hook-source-drift') metadata=k('-n',NS,'exec',POD,'-c',container,'--','sh','-c', 'set -eu; test -f "$1" && test ! -L "$1"; test -f "$2" && test ! -L "$2"; sha256sum "$1" "$2"', 'sh',BASE+'/receive-secret-scan',BASE+'/gitleaks').decode().splitlines() hashes=[s.split()[0] for s in metadata] if hashes!=[ADAPTER,SCANNER]:raise RuntimeError('installed-scanner-artifact-drift') nodes=json.loads(k('get','nodes','-o','json'))['items'] if len(nodes)!=1 or not any(a['address']=='92.205.62.239' for a in nodes[0]['status']['addresses']):raise RuntimeError('node-target-drift') description=k('describe','node',nodes[0]['metadata']['name']).decode() allocation=description.split('Allocated resources:',1)[1].split('Events:',1)[0].strip() if 'Allocated resources:' in description else None if allocation is None:raise RuntimeError('node-headroom-unavailable') receipt=dict(read_only=True,deployment_uid=EXPECTED_UID,pod=POD,pod_uid=POD_UID, deployment_name=NAME,container=container,node_uid=nodes[0]['metadata']['uid'],node_name=nodes[0]['metadata']['name'], guard_index=index,guard_command=guard.get('command'),guard_args=guard.get('args'),volume_index=vindex, volume=volume,strategy=d['spec'].get('strategy'),resources=[dict(name=c['name'],resources=c.get('resources')) for c in spec['containers']], old_configmap=cmname,old_hook_sha256=hashlib.sha256(hook).hexdigest(),old_adapter_sha256=ADAPTER,scanner_sha256=SCANNER, allocated_resources=allocation) pathlib.Path('/tmp/forge-scanner-preflight-receipt.json').write_text(json.dumps(receipt,indent=2)+'\n') # Keep long public shell commands in the local receipt; return concise checks. print(json.dumps({k:receipt[k] for k in ['read_only','deployment_name','deployment_uid','pod_uid','node_uid','old_configmap','old_adapter_sha256','strategy','allocated_resources']},indent=2)) print('receipt: /tmp/forge-scanner-preflight-receipt.json') try:main() except Exception as exc: print('preflight refused:',str(exc) if isinstance(exc,RuntimeError) else type(exc).__name__) sys.exit(1)