Audit-Log prüfen
Jeder Lauf schreibt ein append-only Protokoll: audit-log.jsonl, eine
JSON-Zeile je Schritt. Die Zeilen sind kryptografisch verkettet. Sie müssen
uns nicht glauben, dass niemand nachträglich etwas geändert hat — Sie können
es nachrechnen.
Aufbau einer Zeile
{"seq":1,"ts":"2026-09-03T09:14:22Z","event":"scan.start","data":{"domain":"k••••••••.de","tier":"active"},"prev":"0000…0000","hash":"9c1f…a3d2"}
{"seq":2,"ts":"2026-09-03T09:14:23Z","event":"scope.pin","data":{"host":"k••••••••.de","ip":"203.0.113.17"},"prev":"9c1f…a3d2","hash":"41b8…07ee"}
{"seq":3,"ts":"2026-09-03T09:14:31Z","event":"tool.run","data":{"tool":"testssl.sh","exit":0},"prev":"41b8…07ee","hash":"c05a…9f13"}| Feld | Bedeutung |
|---|---|
seq | fortlaufende Nummer, beginnt bei 1 |
ts | Zeitstempel in UTC |
event | was passiert ist, z. B. scan.start, scope.pin, tool.run, finding.add |
data | die Nutzlast des Ereignisses |
prev | hash der vorigen Zeile; in der ersten Zeile lauter Nullen |
hash | SHA-256 über prev und den kanonisierten Rest der Zeile |
Die Kette
hash(n) = sha256( prev(n) || canonical_json({seq, ts, event, data}) )
prev(n) = hash(n-1), prev(1) = "0" * 64canonical_json bedeutet: Schlüssel alphabetisch sortiert, keine Leerzeichen,
UTF-8 ohne Escape-Sequenzen für Umlaute. Ändert jemand eine Zeile, passt ihr
Hash nicht mehr — und alle folgenden auch nicht.
Die Prüfsumme der letzten Zeile steht auf Seite 14 des PDFs. Stimmt sie mit Ihrer Rechnung überein, ist die Kette unversehrt.
Selbst nachrechnen
#!/usr/bin/env bash
set -euo pipefail
prev=$(printf '0%.0s' {1..64})
line=0
while IFS= read -r entry; do
line=$((line + 1))
body=$(printf '%s' "$entry" | jq -cS '{seq, ts, event, data}')
want=$(printf '%s' "$entry" | jq -r '.hash')
have=$(printf '%s%s' "$prev" "$body" | sha256sum | cut -d' ' -f1)
if [ "$have" != "$want" ]; then
echo "Kette bricht in Zeile $line" >&2
exit 1
fi
prev="$have"
done < audit-log.jsonl
echo "Kette unversehrt, $line Zeilen, Ende $prev"Dieselbe Prüfung läuft serverseitig bei jedem Abruf; das Feld
audit_log_verified in der Scan-Antwort trägt das Ergebnis.
Was es nicht ist
Das Audit-Log beweist, dass das Protokoll nicht nachträglich verändert wurde. Es beweist nicht, dass die Befunde stimmen, und es macht Ihre Daten nicht unlöschbar.