Record archive recovery lifecycle and validate receipt provenance
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a06ecb-456a-71c2-b41e-0755d336e883
This commit is contained in:
codex 2026-09-06 14:53:15 +02:00
parent 445f1361dc
commit a867ec269a
9 changed files with 203 additions and 11 deletions

View file

@ -1,6 +1,7 @@
#!/usr/bin/env python3
"""Silent attended decryption of the hash-verified primary archive download."""
import argparse
from datetime import datetime, timezone
import hashlib
import json
import os
@ -16,12 +17,15 @@ def digest(path):
def main():
p=argparse.ArgumentParser(description=__doc__)
for name in ['source','output','transfer-receipt','receipt']: p.add_argument('--'+name,required=True,type=Path)
a=p.parse_args();receipt={'schema':'platform.forgejo-primary-decryption.v1','status':'failed'}
a=p.parse_args();receipt={'schema':'platform.forgejo-primary-decryption.v1','status':'failed','started_at':datetime.now(timezone.utc).isoformat()}
fd=os.open(a.receipt,os.O_WRONLY|os.O_CREAT|os.O_EXCL,0o600)
try:
transfer=json.loads(a.transfer_receipt.read_text())
if (transfer.get('status')!='primary_fetched_pending_application_restore'
or not transfer.get('download_hash_matches')
raw=a.transfer_receipt.read_bytes()
transfer=json.loads(raw)
receipt['transfer_receipt_sha256']=hashlib.sha256(raw).hexdigest()
if (transfer.get('schema')!='platform.forgejo-primary-archive.v1'
or transfer.get('status')!='primary_fetched_pending_application_restore'
or transfer.get('download_hash_matches') is not True
or digest(a.source)!=transfer.get('ciphertext_sha256')):
raise ValueError('verified_primary_download_required')
value=data(bao(['read','-format=json','platform/data/workloads/railiance/backup/offsite-lane']))['data']['data']['AGE_PRIVATE_KEY']
@ -29,10 +33,15 @@ def main():
a.output.chmod(0o600)
result=subprocess.run(['age','-d','-i','/dev/stdin',str(a.source)],input=(value.strip()+'\n').encode(),stdout=target,stderr=subprocess.PIPE,timeout=1200)
if result.returncode: raise ValueError('primary_decryption_failed')
receipt.update(transfer,decrypted=True,plaintext_sha256=digest(a.output))
# Preserve this operation's schema and times, not the transfer's.
for key in ('destination','ciphertext_sha256','ciphertext_bytes','download_hash_matches','archive_profile'):
if key in transfer: receipt[key]=transfer[key]
receipt.update(status='primary_fetched_pending_application_restore',
decrypted=True,plaintext_sha256=digest(a.output))
except Exception:
receipt['error']='bounded_primary_decryption_failed'
finally:
receipt['finished_at']=datetime.now(timezone.utc).isoformat()
with os.fdopen(fd,'w') as output: json.dump(receipt,output,indent=2)
return int(receipt['status']=='failed')
if __name__=='__main__': raise SystemExit(main())