STEP 11a – AUDIT-LOG INTEGRITAET (HASH-KETTE) Datum: 2026-02-22 Status: ABGESCHLOSSEN ===================================================================== 1. ZIEL ===================================================================== Audit-Log (aza_audit_log.py) manipulations-erkennbar machen durch SHA-256-Hash-Kette, analog zum Consent-Log. ===================================================================== 2. AENDERUNGEN ===================================================================== Datei: aza_audit_log.py a) Neues Format (8 Felder statt 6): TIMESTAMP | EVENT | USER | STATUS | SOURCE | DETAIL | PREV_HASH | ENTRY_HASH b) Hash-Berechnung: entry_hash = SHA-256(prev_hash + payload) payload = "TS | EVENT | USER | STATUS | SOURCE | DETAIL" Startwert (GENESIS): 64x "0" c) Rotation mit Ketten-Uebergabe: Bei Rotation wird der letzte Hash des rotierten Files als Header in der neuen Datei gespeichert: #CHAIN_FROM= Neue Eintraege setzen prev_hash = Chain-Header-Hash. Ein Auditor kann die Kette ueber Dateigrenzen pruefen. d) Neue Funktionen: - verify_integrity(path) -> (bool, list[str]) Prueft eine einzelne Logdatei auf Ketten-Integritaet. - verify_all_rotations() -> (bool, dict) Prueft alle rotierten Dateien. e) CLI-Interface: python -m aza_audit_log verify -> Aktuelle Datei pruefen python -m aza_audit_log verify --all -> Alle Rotationsdateien python -m aza_audit_log verify --file X -> Bestimmte Datei python -m aza_audit_log stats -> Statistiken + Integritaet python -m aza_audit_log export -> JSON-Export mit Integritaet f) Export enthaelt jetzt: - integrity: PASS/FAIL - integrity_errors: [] - Jeder Entry hat prev_hash und entry_hash g) get_log_stats() enthaelt jetzt: - integrity: PASS/FAIL ===================================================================== 3. ROTATIONS-STRATEGIE ===================================================================== Ablauf bei Rotation (Datei > AZA_AUDIT_ROTATE_MB): 1. Letzten entry_hash der aktuellen Datei auslesen 2. Bestehende .1, .2, ... Dateien hochschieben 3. Aktuelle Datei -> .1 verschieben 4. Neue leere Datei anlegen mit Header: #CHAIN_FROM= 5. Neue Eintraege nutzen diesen Hash als prev_hash Verifizierung: - verify_integrity() pro Datei: prueft interne Kette - Header #CHAIN_FROM verbindet die Dateien logisch - verify_all_rotations() prueft alle Dateien der Reihe nach ===================================================================== 4. BEISPIEL LOG-ZEILE ===================================================================== 2026-02-22T21:42:27.160+00:00 | APP_START | user_1 | OK | desktop | test | 000000...0000 | a3f8e1... Felder: [0] Timestamp (UTC, ISO-8601) [1] Event-Typ [2] User-ID [3] Status (OK/FAIL) [4] Source [5] Detail (max 200 Zeichen, keine sensiblen Daten) [6] prev_hash (SHA-256 des vorherigen Eintrags) [7] entry_hash (SHA-256 ueber prev_hash + Felder 0-5) ===================================================================== 5. VERIFY-ANLEITUNG + BEISPIELAUSGABEN ===================================================================== a) Integritaet pruefen (CLI): $ python -m aza_audit_log verify Datei: C:\...\aza_audit.log Integritaet: PASS b) Manipulation erkennen: $ python -m aza_audit_log verify Datei: C:\...\aza_audit.log Integritaet: FAIL Zeile 2: entry_hash stimmt nicht (erwartet 104ebe9a..., gefunden 32e00f09...) c) Alle Rotationsdateien: $ python -m aza_audit_log verify --all aza_audit.1.log: PASS aza_audit.log: PASS GESAMT: PASS d) Statistiken: $ python -m aza_audit_log stats Datei: aza_audit.log Existiert: True Groesse: 0.0 MB Eintraege: 2 Integritaet: PASS ===================================================================== 6. TEST-ERGEBNIS (PROOF) ===================================================================== Testskript: _test_audit_integrity.py 21 Tests, 0 Fehler. Tests: 1. Hash-Kette schreiben + verifizieren: - 5 Eintraege geschrieben, verify PASS - 8 Felder pro Zeile - prev_hash[0] = GENESIS - prev_hash[n] = entry_hash[n-1] 2. Manipulation erkennen: - 1 Zeichen geaendert (LOGIN_OK -> LOGIN_XX) - verify -> FAIL, Fehlerstelle gemeldet - Restore -> PASS 3. Rotation mit Ketten-Uebergabe: - Rotierte Datei (.1) intakt: PASS - Aktuelle Datei mit Chain-Header: PASS - Header-Hash == letzter Hash der rotierten Datei: PASS - prev_hash im neuen File == Chain-Header: PASS - verify_all_rotations: PASS 4. Stats + Export: - Integritaet in Stats: PASS - Export integrity: PASS - Entries mit entry_hash: PASS 5. Data Minimization: - Kein Passwort, kein API-Key, kein Transkript: PASS ===================================================================== 7. DATA MINIMIZATION ===================================================================== Unveraendert gegenueber STEP 11: - Keine Patientennamen - Keine Transkripte/Prompts - Keine Passwoerter/API-Keys - Detail max. 200 Zeichen, nur Metadaten ===================================================================== 8. BETROFFENE DATEIEN ===================================================================== Geaendert: - aza_audit_log.py (Format erweitert, Hash-Kette, verify, CLI) Neu: - _test_audit_integrity.py (Proof-Skript) - security/handovers/STEP_11a_AUDIT_LOG_INTEGRITY.md (dieses Dokument) Nicht geaendert: - basis14.py (Aufrufe bleiben kompatibel, neue Felder transparent) - aza_settings_mixin.py (unveraendert) - aza_consent.py (unveraendert) ===================================================================== 9. RISIKEN ===================================================================== - Performance: _get_last_hash() liest die gesamte Datei. Bei sehr grossen Dateien (kurz vor Rotation) kann dies langsam sein. Akzeptabel, da Rotation bei 10 MB greift. - Rueckwaertskompatibilitaet: Bestehende 6-Feld-Logdateien werden von verify_integrity() als ungueltig gemeldet (< 8 Felder). Loesung: Bestehende Logdatei vor erstem Start archivieren/loeschen. ===================================================================== 10. OFFENE PUNKTE ===================================================================== Keine.