Gegenbuch: externe Notarisierung der Audit-Kette
Abschluss der Anker-Kette. Alle bisherigen Schutzebenen liegen in derselben Datenbank, die sie absichern sollen - der Pentest hat das ueber mehrere Runden Schicht fuer Schicht gezeigt, zuletzt in R174-01 am Siegel-Marker selbst. Aufteilung nach der Analyse des Pentesters (der Schutz kommt vom Ort, nicht von der Signatur): Das CRM liefert nur einen lesbaren Kontrollwert ohne Geheimnisse (GET /api/audit-logs/checkpoint, audit:read). Signiert, zeitgestempelt und angehaengt wird auf einem anderen Rechner - Schluessel und Push-Recht liegen nicht in den Deploy-Secrets des CRM. Ohne diese Trennung waere es D1 nochmal, nur schlimmer: sieht nach doppeltem Boden aus, tut still nichts. Der Kontrollwert enthaelt bewusst maxId. Ein blosser Kopf-Hash erkennt Umschreiben, aber kein Abschneiden am Ende - genau die R174-01-Klasse, eine Ebene hoeher. atId erlaubt der Gegenstelle, einen frueher beglaubigten Kopf erneut abzufragen und nachzurechnen. Gegenstelle: tools/audit-notary/notary.mjs (Cron auf zweitem Rechner, privates Git-Repo als Append-only-Ablage, signierte Commits). Prueft vor dem Anhaengen und bricht bei Widerspruch mit Exit-Code 2 ab, ohne zu schreiben. Verifiziert gegen eine CRM-Attrappe mit echter DB: beglaubigte Zeile veraendert -> Alarm; am Ende abgeschnitten (maxId 5->4) -> Alarm; Gegenbuch selbst gekuerzt (seq-Luecke) -> Alarm; in allen Faellen nichts angehaengt. Ehrlich dokumentiert: Restfenster zwischen zwei Laeufen bleibt und ist inhaerent; ein stiller Cron-Ausfall erzeugt im CRM keine Warnung und muss auf dem Gegenbuch-Rechner ueberwacht werden; Force-Push muss serverseitig gesperrt sein, sonst ist Append-only nur geliehen. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -97,6 +97,38 @@ isolierte Instanz (keine Multi-Tenancy im Code), Provisioning + Abrechnung
|
||||
|
||||
## ✅ Erledigt
|
||||
|
||||
- [x] **⚖️ Gegenbuch: externe Notarisierung der Audit-Kette** (2026-08-18)
|
||||
- Abschluss der Anker-Kette. Alle bisherigen Schutzebenen liegen in
|
||||
derselben Datenbank, die sie absichern sollen – der Pentest hat das ueber
|
||||
mehrere Runden Schicht fuer Schicht gezeigt, zuletzt in R174-01 am Siegel-
|
||||
Marker selbst. Ein Gegenbuch an einem fremden Ort durchbricht das.
|
||||
- Aufteilung nach der Analyse des Pentesters („der Schutz kommt vom ORT,
|
||||
nicht von der Signatur“): Das CRM liefert nur einen **lesbaren
|
||||
Kontrollwert ohne Geheimnisse** (`GET /api/audit-logs/checkpoint`,
|
||||
`audit:read`). Signiert, zeitstempelt und angehaengt wird auf einem
|
||||
**anderen Rechner** – Schluessel und Push-Recht liegen NICHT in den
|
||||
Deploy-Secrets des CRM. Ohne diese Trennung waere es „D1 nochmal, nur
|
||||
schlimmer“: sieht nach doppeltem Boden aus, tut still nichts.
|
||||
- Der Kontrollwert enthaelt bewusst `maxId`. Ein blosser Kopf-Hash erkennt
|
||||
Umschreiben, aber kein **Abschneiden am Ende** – genau die R174-01-Klasse,
|
||||
eine Ebene hoeher. `atId` erlaubt der Gegenstelle, einen frueher
|
||||
beglaubigten Kopf erneut abzufragen und nachzurechnen.
|
||||
- Gegenstelle: `tools/audit-notary/notary.mjs` (Cron auf zweitem Rechner,
|
||||
privates Git-Repo als Append-only-Ablage, signierte Commits). Prueft VOR
|
||||
dem Anhaengen und bricht bei Widerspruch mit Exit-Code 2 ab, **ohne zu
|
||||
schreiben** – der manipulierte Zustand wird nicht als neue Wahrheit
|
||||
festgeschrieben.
|
||||
- Verifiziert gegen eine CRM-Attrappe mit echter DB: beglaubigte Zeile
|
||||
veraendert → Alarm; am Ende abgeschnitten (maxId 5→4) → Alarm; Gegenbuch
|
||||
selbst gekuerzt (seq-Luecke) → Alarm; in allen Faellen nichts angehaengt.
|
||||
Wegwerf-DB und Test-Gegenbuch danach geloescht.
|
||||
- **Ehrlich dokumentiert** (README): Restfenster zwischen zwei Laeufen bleibt
|
||||
und ist inhaerent; ein stiller Cron-Ausfall erzeugt im CRM KEINE Warnung
|
||||
und muss auf dem Gegenbuch-Rechner ueberwacht werden; Force-Push muss
|
||||
serverseitig gesperrt sein, sonst ist Append-only nur geliehen.
|
||||
- **Betrieb:** Einrichtung liegt beim Betreiber (privates Repo, Cron,
|
||||
Signaturschluessel auf dem zweiten Rechner).
|
||||
|
||||
- [x] **🚨 Siegel-Entfernung wird erkannt (Pentest R174-01, HIGH)** (2026-08-18)
|
||||
- Fund: Der Siegelzustand hing **ausschliesslich** am Marker im Audit-Log –
|
||||
und den kann ein DB-Schreiber **ohne Schluessel** loeschen. Danach meldete
|
||||
|
||||
Reference in New Issue
Block a user