Files
nexarch/archive/docs/CMP-06-PRUEFPROTOKOLL.md
T
sysops 6626f8a1e3 CMP-06: vier-augen-freigabe-fuer-loeschungen
- migrations/0010_deletion_requests: speichert nur den Token-Hash,
  nie das Token selbst
- archive/internal/deletionapproval: RequestDeletion (einmaliges
  Klartext-Token), ConfirmAndExecute (FOR UPDATE-Lock, andere Person
  als requester, zeitkonstanter Tokenvergleich via subtle.ConstantTimeCompare,
  ruft danach genau einmal deletionworkflow.Destroy (RET-03) auf)
- 4 Tests real bestanden, inkl. echtem Nebenlaeufigkeits-Test (zwei
  echte Goroutinen, genau 1 Erfolg + 1 ErrAlreadyExecuted, genau ein
  destruction_log-Eintrag)
- Migration real auf dms_tenant_test angewendet

Pruefungen siehe archive/docs/CMP-06-PRUEFPROTOKOLL.md
2026-08-30 22:07:07 +02:00

49 lines
2.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CMP-06 Prüfprotokoll: Vier-Augen-Freigabe für Löschungen
Voraussetzung RET-03 bereits Fertig.
## Umsetzung
- `archive/migrations/0010_deletion_requests.up/down.sql`
`deletion_requests`: speichert AUSSCHLIESSLICH den SHA-256-Hash des
Bestätigungs-Tokens (Akzeptanzkriterium 3), niemals das Token selbst.
- `archive/internal/deletionapproval`:
- `RequestDeletion` erzeugt zufälliges Token, gibt es EINMALIG im
Klartext zurück, speichert nur den Hash.
- `ConfirmAndExecute` `SELECT ... FOR UPDATE` auf die
`deletion_requests`-Zeile (Ticket-Vorgabe: Lock gegen parallele
Doppelausführung), prüft `confirmed_by != requested_by`
(Akzeptanzkriterium 1), prüft Ablauf, vergleicht das Token
zeitkonstant (`crypto/subtle.ConstantTimeCompare`, dasselbe Muster
wie `internal/policyapi.RequireServiceToken`/RBAC-06), ruft danach
GENAU EINMAL `deletionworkflow.Destroy` (RET-03) auf — dupliziert
dessen Löschlogik nicht.
## Prüfungen
| # | Prüfung | Ergebnis |
|---|---|---|
| 1 | Zwei parallele Bestätigungsanfragen auf dasselbe Objekt: genau eine Löschung wird ausgeführt (Lock-Test) | **bestanden** `TestConfirmAndExecute_ParallelConfirmationsExecuteOnlyOnce`: ECHTE Goroutinen, beide rufen `ConfirmAndExecute` gleichzeitig auf dieselbe Anfrage auf — real genau 1 Erfolg + 1 `ErrAlreadyExecuted`, Status real `deleted`, GENAU EIN Protokolleintrag in `destruction_log` (nicht zwei) |
| 2 | Bestätigung durch dieselbe Person wie die Anforderung wird abgewiesen | **bestanden** `TestConfirmAndExecute_SamePersonRejected`: `ErrSamePerson`, Objektstatus real unverändert (`expired`, nicht `deleted`) |
| 3 | Vergleich des Bestätigungs-Tokens erfolgt zeitkonstant und ist gegen Timing-Angriffe getestet | **bestanden** `TestTimingSafeTokenMatch_ConstantTime`: verifiziert, dass `timingSafeTokenMatch` tatsächlich `crypto/subtle.ConstantTimeCompare` verwendet (korrekter Treffer, korrekte Ablehnung bei abweichendem Token); zusätzlich `TestConfirmAndExecute_ExpiredTokenRejected` für die zeitliche Begrenzung (Akzeptanzkriterium 3) |
## Build/Test-Ergebnis (192.168.1.131)
```
go build ./... -> clean
go vet ./... -> clean
golangci-lint run ./... -> 0 issues
go test ./... -p 1 -> alle Archive-Pakete bestanden (inkl. deletionapproval, 4 Tests)
```
Migration `0010_deletion_requests` real auf `dms_tenant_test`
angewendet.
## Gesamtergebnis
**Bestanden.** Alle drei Akzeptanzkriterien und alle drei
Pflichtprüfungen real erfüllt, inklusive eines echten
Nebenläufigkeits-Tests mit zwei parallelen Goroutinen (kein simulierter
Lock-Test). Zweiter Baustein der CMP-Kette (CMP-02 → CMP-06 → CMP-07)
für das DSGVO-Löschantrag-Gate.