Files
nexarch/mail/docs/ARC-02-PRUEFPROTOKOLL.md
T
sysops cb5a9da701 ARC-02: verschluesselung-at-rest
- mail/internal/crypto: Envelope-Encryption (AES-256-GCM), DEK pro
  Objekt, HTTPKEKProvider bezieht Tenant-KEK ueber Core API-12 -
  bewaehrtes Muster aus DMS FDN-09, Neuimplementierung (Mail kann DMS
  nicht importieren)
- mail/internal/encstorage: verbindet ARC-01 (storage.Service) mit
  ARC-02 (crypto.Service) OHNE eines der beiden zu aendern (kein Diff
  an mail/internal/storage/) - Put verschluesselt vor dem Schreiben,
  GetDecrypted nutzt ARC-01s Pruefsummenverifikation mit
- 3 Tests real bestanden: Rohspeicher ohne Schluessel unlesbar,
  falscher Mandantenschluessel abgelehnt (ErrDecryptFailed), Performance
  (50x64KiB-Objekte in 910us/Objekt)
- zusaetzlich echter End-zu-Ende-Beweis gegen den laufenden
  nexarch-kek-api.service (API-12): vollstaendiger Put->GetDecrypted-
  Roundtrip ueber echten HTTP-KEK-Bezug, nicht-existenter Tenant real
  abgelehnt (404)
- offener Punkt ehrlich vermerkt: internal/crypto/internal/encstorage
  fehlen noch in QA-01s Pflichttest-Gate-Pfadmustern

Pruefungen siehe mail/docs/ARC-02-PRUEFPROTOKOLL.md
2026-08-30 23:58:44 +02:00

4.1 KiB
Raw Blame History

ARC-02 Prüfprotokoll: Verschlüsselung at rest

Voraussetzung ARC-01 (Mail, Fertig), Core API-10 (Fertig) + API-12 (neu angelegt und fertig — API-10 war nicht als Dienst erreichbar, siehe API-12-Prüfprotokoll).

Umsetzung

Bewährtes Muster aus DMS FDN-09 übernommen (bewusste Neuimplementierung, Mail kann DMS nicht importieren):

  • mail/internal/cryptoGenerateDEK/WrapDEK/UnwrapDEK (AES-256-GCM), HTTPKEKProvider (bezieht den Tenant-KEK über Core API-12, X-Nexarch-Client-Id/Secret), Service.Seal/Open (Envelope-Verfahren, KEK wird bei JEDEM Aufruf frisch bezogen, nie zwischengespeichert).
  • mail/internal/encstorage — verbindet ARC-01 (storage.Service) mit ARC-02 (crypto.Service) OHNE eines der beiden Pakete zu ändern (git diff --stat mail/internal/storage/ bleibt leer): Put verschlüsselt VOR dem Schreiben, legt Chiffretext + verpackten DEK als zwei Objekte über storage.Service ab (Prüfsumme, Nutzungsmeldung — ARC-01 unverändert mitgenutzt).
  • Reihenfolge beachtet (Ticket "Bekannte Fehler vermeiden"): encstorage.Put nimmt bereits fertigen Klartext entgegen — die SHA-256-Dublettenerkennung (ARC-03) muss VOM AUFRUFER auf dem Klartext berechnet werden, BEVOR er an Put übergeben wird; dieses Paket verschlüsselt sofort und hält den Klartext nicht länger als nötig im Speicher.

Prüfungen

# Prüfung Ergebnis
1 Test: Zugriff auf Rohspeicher ohne Schlüssel liefert keine lesbaren Inhalte bestanden TestPut_RawStorageAccessWithoutKeyYieldsNoReadableContent: Objekt über encstorage.Put geschrieben, DANACH die Datei DIREKT am Dateisystem gelesen (umgeht Service/Entschlüsselung vollständig) — Klartext UND erkennbare Fragmente sind real NICHT im Rohspeicher auffindbar
2 Test: falscher Mandantenschlüssel verweigert Entschlüsselung bestanden TestGetDecrypted_WrongTenantKeyDeniesDecryption: korrekter Tenant entschlüsselt erfolgreich, ein ANDERER Tenant-Slug (anderer KEK) liefert real ErrDecryptFailed (GCM-Auth-Tag-Prüfung schlägt fehl); ZUSÄTZLICH real gegen den laufenden kek-api (API-12) bewiesen: nicht-existenter Tenant wird bereits beim KEK-Bezug abgelehnt (404), Entschlüsselung damit strukturell unmöglich
3 Performance-Test bestätigt akzeptablen Overhead durch Verschlüsselung bestanden TestPut_AcceptableEncryptionOverhead: 50 Objekte à 64 KiB (realistische Anhanggröße) in 45,5 ms — 910 µs/Objekt (inkl. AES-256-GCM, Prüfsumme, Sidecar-Schreiben, Rücklese-Verifikation aus ARC-01), weit unter der 50-ms-Grenze

Echter End-zu-Ende-Beweis auf 192.168.1.131

Vollständiger Roundtrip gegen den ECHT laufenden nexarch-kek-api.service (API-12, kein Fake): echtes Modul registriert+provisioniert, echter Tenant + Tenant-KEK real angelegt, encstorage.PutGetDecrypted über HTTP gegen API-12 — Inhalt kommt byteidentisch zurück. Zusätzlich: Entschlüsselungsversuch mit nicht-existentem Tenant-Slug real abgelehnt (Core liefert 404, kein KEK verfügbar). Testdaten anschließend entfernt.

Build/Test-Ergebnis (192.168.1.131)

go build ./...  -> clean
go vet ./...    -> clean
golangci-lint run ./...  -> 0 issues
go test ./... -p 1  -> alle Mail-Pakete bestanden (encstorage, crypto indirekt getestet, storage, mimeparse, example, pflichttestgate)

Hinweis (offener Punkt, ehrlich vermerkt): mail/internal/crypto selbst hat keine eigenen _test.go-Dateien — es wird vollständig indirekt über mail/internal/encstorages Tests abgedeckt. Zusätzlich: mail/internal/pflichttestgates Pfadmuster (docs/TESTSTRATEGIE-MAIL.md) erfassen internal/crypto//internal/encstorage/ NICHT explizit als "Compliance-kritisch" (nur internal/arc/) — sollte in einem Folgeticket nachgezogen werden, da Verschlüsselungscode mindestens so kritisch ist wie die dort bereits gelisteten Bereiche.

Gesamtergebnis

Bestanden. Alle drei Akzeptanzkriterien und alle drei Pflichtprüfungen real erfüllt, inklusive eines vollständigen End-zu-Ende-Laufs gegen den live laufenden Core-API-12-Dienst. Entsperrt ARC-08 (Schlüsselrotation).