Implement authenticated alert receipt acknowledgments and audit delivery

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e6f1-443f-7783-9920-a16b2ffc467f
This commit is contained in:
tegwick 2026-09-28 11:11:33 +02:00
parent 67283b66c2
commit e7282e493d
25 changed files with 1881 additions and 0 deletions

View file

@ -0,0 +1,48 @@
"""Opt in with RTEL_AUDIT_CORE_SOURCE; uses the real receiver, synthetic custody."""
import io
import json
import os
from pathlib import Path
import sys
import tempfile
import unittest
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / 'scripts'))
from alert_ack import Actor, Store
@unittest.skipUnless(os.environ.get('RTEL_AUDIT_CORE_SOURCE'), 'set RTEL_AUDIT_CORE_SOURCE for real receiver check')
class NativeAuditTests(unittest.TestCase):
def test_real_receiver_accepts_and_deduplicates_after_lost_reply(self):
sys.path.insert(0, os.environ['RTEL_AUDIT_CORE_SOURCE'])
from audit_core.ingestion import IngestionApplication
from audit_core.senders import SenderIdentity, SenderRegistry
from audit_core.sqlite_backend import SQLiteAuditBackend
with tempfile.TemporaryDirectory() as tmp:
store = Store(Path(tmp) / 'ack.db')
identity = store.receive({'version': '4', 'receiver': 'railiance-admin-email', 'alerts': [
{'status': 'firing', 'fingerprint': '0123456789abcdef', 'startsAt': '2026-09-28T00:00:00Z',
'labels': {'alertname': 'ControlledFailure', 'owner': 'railiance-telemetry'}}]}, 1790553600)[0]
store.acknowledge(identity, Actor('https://issuer.example', 'fixture-human', 'tenant:platform',
('railiance-admin',), 1790554500, 'c' * 32), 'fixture-decision', 1790553600)
sender = SenderIdentity(name='railiance-telemetry', tokens=('fixture-only',),
sources=frozenset({'railiance-telemetry'}), tenants=frozenset({'tenant:platform'}),
evidence_kind='load-bearing', may_read=False)
app = IngestionApplication(SQLiteAuditBackend(str(Path(tmp) / 'audit.db')), SenderRegistry([sender]))
calls = []
def send(event):
raw = json.dumps(event).encode()
env = {'REQUEST_METHOD': 'POST', 'PATH_INFO': '/v1/events',
'CONTENT_LENGTH': str(len(raw)), 'wsgi.input': io.BytesIO(raw),
'HTTP_AUTHORIZATION': 'Bearer fixture-only', 'HTTP_IDEMPOTENCY_KEY': event['id']}
response = {}
body = b''.join(app(env, lambda status, headers: response.update(status=int(status[:3]))))
calls.append(response['status'])
if len(calls) == 1:
raise TimeoutError('simulated lost response')
return response['status'], json.loads(body)
store.drain(send)
store = Store(Path(tmp) / 'ack.db')
store.drain(send)
self.assertEqual(calls, [202, 200])
self.assertEqual(store.get(identity)['audit_status'], 'delivered')