#!/usr/bin/env python3 """Root-owned Railiance backup job. No operator password or age private key. Publisher and retention are separate processes with separate scoped delivery. Scheduled execution is gated by an independently recovered archive receipt. """ import argparse import base64 from datetime import datetime,timezone import fcntl import importlib.util import json import os from pathlib import Path import signal import shutil import socket import tempfile import urllib.request HERE=Path(__file__).resolve().parent def load(name): spec=importlib.util.spec_from_file_location(name,HERE/(name+'.py')) m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m);return m capture=load('capture-identity');offsite=load('identity-offsite');retention=load('identity-retention') def write(path,value): fd,name=tempfile.mkstemp(prefix='.identity-receipt-',dir=path.parent) try: with os.fdopen(fd,'w') as out:json.dump(value,out,indent=2);out.write('\n');out.flush();os.fsync(out.fileno()) os.replace(name,path) finally:Path(name).unlink(missing_ok=True) def token(action): name='net-kingdom-backup-'+action es=capture.get('sso','externalsecret',name) entries=[] for entry in es['spec'].get('data',[]): item=dict(entry);ref=dict(item.get('remoteRef',{})) for key,default in [('conversionStrategy','Default'),('decodingStrategy','None'),('metadataPolicy','None')]: if ref.pop(key,default)!=default:raise offsite.Refused() item['remoteRef']=ref;entries.append(item) if (es['spec']['target']['name']!=name or entries!=[{'secretKey':'token','remoteRef':{ 'key':'workloads/net-kingdom/identity-backup/'+action,'property':'NC_WEBDAV_TOKEN'}}] or es['spec'].get('dataFrom') or es['spec'].get('secretStoreRef')!={'kind':'SecretStore','name':name} or not any(c['type']=='Ready' and c['status']=='True' for c in es['status'].get('conditions',[]))):raise offsite.Refused() secret=capture.get('sso','secret',name) if (set(secret['data'])!={'token'} or not any(o['uid']==es['metadata']['uid'] for o in secret['metadata'].get('ownerReferences',[]))):raise offsite.Refused() value=base64.b64decode(secret['data']['token'],validate=True).decode();offsite.headers(value) return value def accepted(path): capture.bundle.private(path) r=json.loads(path.read_text()) if (r.get('schema')!='netkingdom.identity-recovery.v1' or r.get('status')!='identity_archive_verified' or r.get('all_manifest_hashes_verified') is not True or r.get('container_cleanup_verified') is not True or r.get('temporary_plaintext_cleanup_verified') is not True or not offsite.NAME.fullmatch(r.get('artifact',''))):raise offsite.Refused() return r def post_event(state,summary): # Non-secret durable reporting: replay retained notes at the next run. directory=state/'event-outbox';directory.mkdir(mode=0o700,exist_ok=True) import uuid path=directory/(uuid.uuid4().hex+'.json') write(path,{'summary':summary,'event_type':'note','author':'net-kingdom-identity-backup', 'workplan_id':'17d315f0-829e-57c7-85cc-3a7914152804','task_id':'d68cd4d3-1ba3-530e-88f9-26ebb8dd6eac'}) for pending in sorted(directory.glob('*.json'))[:64]: request=urllib.request.Request('http://10.43.68.154:8000/progress/',data=pending.read_bytes(), headers={'Content-Type':'application/json'},method='POST') try: with urllib.request.build_opener(urllib.request.ProxyHandler({})).open(request,timeout=10) as response: if response.status!=201:break pending.unlink() except Exception:break def backup(state,decision,first=False): if not first:accepted(state/'accepted-recovery.json') if (state/'capture-in-progress.json').exists():raise offsite.Refused() publisher=token('publisher') client=offsite.opener() if offsite.quota(client,publisher)