Add audit maintenance, verified recovery and reproducible verification

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e6f1-443f-7783-9920-a16b2ffc467f
This commit is contained in:
tegwick 2026-09-28 11:48:01 +02:00
parent 820f0ff7b5
commit 3166da1d2e
13 changed files with 413 additions and 5 deletions

View file

@ -7,6 +7,7 @@ import os
from pathlib import Path
import secrets
import signal
import sqlite3
import threading
import time
from urllib.parse import parse_qs
@ -61,6 +62,11 @@ class Router:
return ('Set-Cookie', f'{name}={value}; Path=/; Secure; HttpOnly; SameSite=Lax; Max-Age={age}')
path, method = env.get('PATH_INFO'), env.get('REQUEST_METHOD')
try:
if method == 'GET' and path == '/metrics':
body = self.store.audit_metrics(self.last_drain)
start('200 OK', [('Content-Type', 'text/plain; version=0.0.4; charset=utf-8'),
('Cache-Control', 'no-store')])
return [body.encode()]
if method == 'GET' and path in ('/healthz', '/readyz'):
ready = path == '/healthz' or time.time() - self.last_drain < 90 and not self.store.audit_debt()
return reply('200 OK' if ready else '503 Service Unavailable', 'ready' if ready else 'audit delivery pending')
@ -87,7 +93,7 @@ class Router:
if path == '/webhook':
self.application.webhook_token = credential(self.config['webhook_token_file'])
return self.application(env, start)
except (ValueError, OSError, KeyError, TypeError):
except (ValueError, OSError, KeyError, TypeError, sqlite3.Error):
return reply('503 Service Unavailable', 'Identity or service unavailable. Retry later.')
@ -109,7 +115,7 @@ def main():
try:
store.drain(transport)
router.last_drain = time.time()
except (OSError, ValueError):
except (OSError, ValueError, sqlite3.Error):
router.last_drain = 0
stop.wait(30)
worker = threading.Thread(target=drain, daemon=True)