Files
aza/AzA march 2026/security/handovers/STEP_11a_AUDIT_LOG_INTEGRITY.md

198 lines
6.2 KiB
Markdown
Raw Normal View History

2026-03-25 22:03:39 +01:00
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=<letzter_entry_hash>
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=<letzter_hash>
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.