Files
archivmail/docs/GOBD_DSGVO_CHECKLIST.md
T
sysops 6d67a6bbe7 docs: GoBD-Checklist auf aktuellen Stand bringen, Spec für PROJ-56c nachtragen
Checklist war seit 2026-06-13 nicht aktualisiert: PROJ-48/49/50/51/52 waren
laengst deployt, standen aber noch als fehlend/teilweise drin. PROJ-56c
(Cron-Purge mit Markierungspflicht) war im Code implementiert, hatte aber
nie eine eigene Feature-Spec — nachtraeglich dokumentiert.
2026-07-04 12:12:08 +02:00

9.1 KiB
Raw Blame History

GoBD/DSGVO-Compliance-Checkliste archivmail

Bewertung gegen den "Leitfaden zur E-Mail-Archivierung in Deutschland" (VOI-Grundsätze, GoBD, DSGVO). Stand: 2026-07-04, basierend auf Code-Review (nicht nur Spec-Review).

Zusammenfassung

Gut abgedeckt: Verschlüsselung at-rest (AES-256-GCM) mit Pflicht-Warnung (PROJ-49), Volltextsuche (Manticore), unveränderliches Audit-Log per DB-Trigger + append-only JSON-Lines (PROJ-48), Retention/Löschsperre inkl. Dokumentenart-Kategorien (PROJ-34, PROJ-51), DSGVO-Löschersuchen-Workflow mit GoBD-Vorrang (PROJ-50), Vollständigkeits-Reconciliation (PROJ-52), Multi-Tenant-Rollenmodell, Integritätsprüfung per SHA-256 (PROJ-18), Export in EML/MBOX/ZIP/CSV (PROJ-12, PROJ-15, PROJ-39, PROJ-47).

Verbleibende Lücken (priorisiert):

  1. Migrationssicherheit teilweise kein dokumentierter Compliance-Erhalt-Check nach Schema-/ Index-Migrationen (Punkt 10).
  2. Physische Tenant-Trennung fehlt Storage ist logisch (DB) getrennt, nicht auf Dateisystem- Ebene (Punkt 15, bekannt seit Tenant-Isolation-Review).
  3. Zeitstempel/Signaturerhalt (BSI TR 03125) nicht implementiert (Nice-to-have, niedrige Priorität, nur relevant bei signierten Mails im Kundenkreis).
  4. Informationspflicht der Mitarbeiter organisatorisch, nicht im Code lösbar (Punkt 13).

Checkliste

# Anforderung Status Begründung / Codeverweis Empfehlung
1 Vollständigkeit 100% Ein-/Ausgang archiviert Erfüllt SMTP-BCC-Journal (PROJ-4), IMAP/POP3-Import (PROJ-3/14), EML/MBOX-Import (PROJ-2). SMTP-Daemon (internal/smtpd/smtpd.go) gibt bei Storage-Fehler 452 zurück → MTA-Retry, kein Verlust beim Empfang. Vollständigkeits-Reconciliation (PROJ-52, deployt 2026-07-04): täglicher Cron-Report internal/reconciliation/ zählt archivierte Mails je Quelle, Alert bei >50% Abweichung vom 7-Tage-Schnitt, Audit-Eintrag reconciliation_anomaly.
2 Frühzeitigkeit Archivierung bei Eingang/Ausgang Erfüllt SMTP-BCC-Journaling (PROJ-4) archiviert synchron beim Empfang/Versand; IMAP-Cron-Sync (PROJ-8) ergänzt. internal/storage/storage.go:343 Save() läuft direkt im Empfangspfad.
3 Unveränderbarkeit / Formaterhalt Erfüllt Save() speichert Original-RFC2822-Bytes (ggf. gzip-komprimiert, PROJ-36) ohne inhaltliche Konvertierung; Load()/maybeDecompress() liefert Original zurück. Export liefert EML 1:1 (PROJ-12, internal/api/export.go). Kein Schreibzugriff/UPDATE auf gespeicherte Mail-Dateien im Code gefunden.
4 Zugriffsschutz Erfüllt JWT-Auth (httpOnly Cookie), bcrypt Cost 12 (PROJ-1). Rollenmodell user/auditor/admin strikt getrennt; admin hat explizit KEINEN Mail-Zugriff. Tenant-Isolation via tenantAccessAllowed() (internal/api/import_handlers.go:22).
5 Wiederauffindbarkeit / Volltextsuche Erfüllt Manticore-RT-Index (PROJ-30), Volltextsuche inkl. Anhänge via OCR (PROJ-35/44), Filter nach Datum/Absender/etc. (PROJ-6).
6 Aufbewahrungsfristen (konfigurierbar je Dokumentenart, i.d.R. 610 Jahre) Erfüllt PROJ-51 (deployt 2026-06-13): Tabelle archiving_rules (internal/storage/retention_rules.go) — Muster-Regeln (Absender/Betreff/etc.) mit individueller retention_days pro Dokumentenart, Priorität bei mehreren Treffern, retain_until_source dokumentiert welche Regel griff. Store.minRetentionDays/SetMinRetentionDays erzwingt konfigurierbares Minimum. Admin-UI unter /api/admin/archiving-rules.
7 Löschsperre Erfüllt PROJ-34 implementiert: emails.retain_until, ErrRetentionLock (internal/storage/storage.go:27,659-667), Delete() verweigert Löschung vor Fristablauf. Zusätzlich Cron-Purge (PROJ-56c, cmd/archivmail/cmd_purge.go, nachts 03:40 via /etc/cron.d/archivmail): löscht NUR Mails die BEIDE Bedingungen erfüllen — retain_until < NOW() UND vom Nutzer explizit marked_for_deletion=TRUE gesetzt (ListExpiredMarkedMailIDs, internal/storage/mark_deletion.go:127-148). Reiner Fristablauf ohne manuelle Markierung löscht nichts automatisch (Vier-Augen-Prinzip: Frist + Mensch). Der manuelle Admin-Button (Store.Purge(), POST /api/admin/purge) löscht dagegen alles abgelaufene ohne Markierungspflicht — bewusst getrennte, absichtlich unterschiedliche Semantik für Cron vs. manuelle Aktion.
8 Protokollierung/Audit-Log unveränderlich Erfüllt PROJ-48 (deployt 2026-06-13): internal/audit/audit.go installiert Funktion audit_log_no_mutation() + Trigger audit_log_immutable (blockt UPDATE/DELETE auf DB-Ebene, idempotent via CREATE OR REPLACE/DROP TRIGGER IF EXISTS). Zusätzlich append-only JSON-Lines-Datei (ResolvedLogPath(), Default /var/log/archivmail/audit.log), Schreibfehler blockieren den DB-Pfad nicht (best effort, DB bleibt Quelle der Wahrheit).
9 Nachprüfbarkeit durch Dritte / GDPdU-Export Erfüllt Export-Funktionen: Einzel-EML/PDF, ZIP-Massenexport mit manifest.csv (PROJ-12, internal/api/export.go), eDiscovery-ZIP mit metadata.csv + README (PROJ-39, internal/api/ediscovery.go), CLI-Export inkl. Tenant-Voll-Export (PROJ-15, PROJ-47, cmd/archivmail/cmd_export.go), Audit-Log-CSV-Export für Auditoren. Optional: PROJ-47 (In Review) fertigstellen/QA.
10 Migrationssicherheit ⚠️ Teilweise Migrationstools vorhanden (PROJ-19 Mailpiler-Import, PROJ-30 Xapian→Manticore), initSchema/idempotente ALTER TABLE ... ADD COLUMN IF NOT EXISTS Pattern durchgängig genutzt (z.B. storage.go:99-100). Kein dokumentierter "Compliance-Erhalt-Check" nach Migration (z.B. automatischer Verify-Lauf nach Schema-Änderung). Migrations-Runbook + Post-Migration-Integritätscheck (kann PROJ-18-Job nach Migration triggern) dokumentieren.
11 Maschinelle Auswertbarkeit (Standardformate) Erfüllt Export als EML (Original-MIME, PROJ-12/15), MBOX (cmd_export.go), CSV-Metadaten (PROJ-39).
12 Zeitstempel/Signaturerhalt (BSI TR 03125) Fehlt Keine S/MIME- oder PGP-Signaturprüfung, kein qualifizierter Zeitstempel-Dienst im Code gefunden. Für die meisten KMU nicht zwingend erforderlich. Als Backlog-Item vermerken, nur bei Bedarf (signierte Mails im Kundenkreis) als neue Spec aufnehmen.
13 Informationspflicht der Mitarbeiter Fehlt (organisatorisch) Nicht im Code prüfbar/lösbar. Organisatorische Maßnahme: Betriebsvereinbarung / Datenschutzhinweis außerhalb des Systems.
14 Trennung/Kennzeichnung personenbezogener Daten, Löschkonflikt Art. 5/17/32 Erfüllt PROJ-50 (deployt 2026-06-13): internal/storage/dsgvo_requests.go — Tabelle dsgvo_requests, Workflow sucht betroffene Mails (From/To/CC, Volltext via Manticore AnyAddress), löscht NUR Mails ohne aktive Löschsperre (store.Delete respektiert retain_until), lehnt den Rest mit Begründung "Aufbewahrungspflicht hat Vorrang" ab und protokolliert (EventDSGVORequest). Bekannte Deviation: bcc_addr ist im Schema vorhanden, aber mailparser befüllt BCC nicht (kein BCC-Header in archivierten Mails) — Such-Vollständigkeitszusage entsprechend einschränken. Deviation (BCC) in Kunden-Doku erwähnen, sonst keine Aktion nötig.
15 Mandantentrennung/Zugriffskontrolle nach Rolle (Multi-Tenant) Erfüllt PROJ-21 Multi-Tenancy, tenantAccessAllowed() als Standardmuster (internal/api/import_handlers.go:22), Tenant-Quotas (PROJ-29), Pro-Tenant-Retention (tenants.retention_days). Laut Memory: keine physische Storage-Trennung pro Tenant (logische Trennung über email_refs/DB). Bekannte Lücke (siehe Memory project_tenant_isolation_review.md): physische Storage-Trennung als optionales Härtungsfeature evaluieren, falls von Kunden gefordert.
16 Verschlüsselung at-rest Erfüllt PROJ-49 (deployt 2026-06-13): AES-256-GCM (internal/storage/storage.go, encrypt()), inkl. gzip vor Verschlüsselung (PROJ-36). Store.EncryptionEnabled() + warnEncryptionStatus() gibt beim Start eine WARN-Zeile aus wenn Keyfile fehlt/unlesbar/falsche Größe; archivmail status prüft checkEncryption; Dashboard (handleSystemStats) zeigt encryption.enabled systemweit. Keyfile bleibt technisch optional (Abwärtskompatibilität bestehender Installationen), aber Zustand ist jetzt sichtbar statt stillschweigend.

Nächste Schritte (Vorschlag, Priorität absteigend)

  1. Migrations-Runbook (Punkt 10): Compliance-Erhalt-Check nach Schema-/Index-Migrationen dokumentieren (kann PROJ-18-Integritätsjob nach Migration triggern).
  2. Physische Tenant-Trennung (Punkt 15) evaluieren, falls von Kunden gefordert (siehe Memory project_tenant_isolation_review.md).
  3. Nice-to-have: BSI TR 03125 Zeitstempel/Signaturerhalt (Punkt 12), nur bei konkretem Bedarf.
  4. Organisatorisch: Mitarbeiter-Informationspflicht (Punkt 13) außerhalb des Codes klären.

Erledigt seit Stand 2026-06-13: PROJ-48 (Audit-Log-Unveränderbarkeit), PROJ-49 (Verschlüsselungspflicht/Warnung), PROJ-50 (DSGVO-Löschersuchen), PROJ-51 (Retention-Kategorien), PROJ-52 (Vollständigkeits-Reconciliation), PROJ-47 (Tenant-Voll-Export, jetzt Deployed).