ProofedMesh/docs/adr/0003-pii-retention-policy.md

109 lines
6.2 KiB
Markdown
Raw Normal View History

# ADR-0003: PII-Retention-Richtlinie
- **Status:** accepted
- **Datum:** 2026-10-25
- **Entscheider:** CEO (A. Leinen), CTO
- **Betroffene Dokumente:** `docs/architecture/v1.1.md` Abschnitte 8.1, 8.2, 8.4
## Kontext und Problemstellung
Der PII-Store (siehe `docs/architecture/v1.1.md` 8.4) hält personenbezogene Daten (Belege, kanonische Reisekostendaten, Query-Ergebnisse mit Namen und Zuordnungen) getrennt vom Evidence Store. Dieser muss zwei Anforderungen gleichzeitig erfüllen:
1. **DSGVO Art. 17 „Recht auf Löschung"** — Betroffene müssen ihre personenbezogenen Daten löschen lassen können.
2. **Kryptografischer Nachweis einer unverfälschten Kommunikation während eines sinnvollen Zeitraums** — Attestierungen müssen Nachkontrollen gegen den Originalinhalt erlauben, solange ein berechtigtes Interesse besteht.
Festzulegen: wie lange halten wir PII-Daten auf, wann wird gelöscht, wie wird eine vorzeitige Löschung ausgeführt, und wie wird die Löschung ihrerseits nachweisbar?
## Entscheidungsoptionen
- **Option A — Default-Retention 1 Jahr, mit konfigurierbarer Verkürzung pro Prozess-Typ.** Nach Ablauf automatische Cryptographic Erasure. Betroffene können jederzeit vorzeitige Löschung beantragen.
- **Option B — Default-Retention 90 Tage** — kürzer, aber möglicherweise zu kurz für realistische Nachprüfungen (Jahresabschluss, interne Audits).
- **Option C — Default-Retention 3 Jahre** — richtet sich an GoBD-Fristen aus; widerspricht aber der grundsätzlichen Entscheidung „kein rechtssicheres Archiv" (ADR-0001 bzw. `docs/architecture/v1.1.md` 8.1).
## Entscheidung
**Option A.**
Konkrete Regeln:
### Default-Retention
- **1 Jahr** ab letzter Workflow-Aktivität (letzte Attestierung, Decision oder Deletion-Anfrage, je nachdem was später ist).
- Konfigurierbar **pro Prozess-Typ** (`workflow_type.retention_days`) und **pro Senke/Datenquelle** (`sinks.retention_days`, `data_sources.retention_days`), jeweils als Default-Override.
- Minimum: 30 Tage (unter diesem Wert ist kein Review mehr sinnvoll). Maximum: 2 Jahre (darüber kippt die „kein rechtssicheres Archiv"-Positionierung).
### Automatische Löschung
- Cron-Job `pii-retention-sweeper` läuft **täglich 03:30 UTC**.
- Für jeden Workflow mit `last_activity_at + retention_days < NOW()`:
1. Alle PII-Objekte des Workflows aus dem S3-Bucket entfernen.
2. Alle Envelope-Keys im OpenBao Transit vergessen (Cryptographic Erasure).
3. Eine signierte **PII-Deletion-Attestierung** in den Transparency Log schreiben (`predicateType=https://basicstack.de/attestations/pii_deletion/v1`).
4. Workflow-Status auf `pii_purged` setzen; der Evidence-Store-Eintrag bleibt bestehen.
### Vorzeitige Löschung auf Antrag
- Endpunkt `DELETE /pii/<workflow_id>` am PII-Mediator mit Admin-Auth.
- Zusätzlich: Endpunkt `DELETE /pii/by-subject/<user_sub>` löscht alle Workflows, in denen der angegebene Benutzer `original_user.sub` ist. Für DSGVO-Antragsabwicklung.
- Ablauf identisch zur automatischen Löschung (Schritte 1–4 oben).
### Löschung-vs-Signaturkette
- Signaturkette im Evidence Store wird **nicht** angerührt.
- Hashes in Attestierungen bleiben prüfbar; Nachkontrolle gegen den Inhalt ist nach Löschung nicht mehr möglich — das ist der bewusste Trade-off.
- Verification Service markiert Verifikationsantworten, deren materials-Hashes nicht mehr im PII-Store auflösbar sind, mit `content_check: "pii_purged"` (statt `pii_matched`).
### PII-Deletion-Attestierung (neue predicate)
```json
{
"_type": "https://in-toto.io/Statement/v1",
"subject": [
{ "name": "pii/<workflow_id>", "digest": { "sha256": "<hash of deleted objects manifest>" } }
],
"predicateType": "https://basicstack.de/attestations/pii_deletion/v1",
"predicate": {
"workflow_id": "WF-...",
"deletion_reason": "retention_policy_expired" | "subject_erasure_request" | "operator_action",
"deleted_objects": [ { "pii_store_ref": "pii://...", "content_hash_before_delete": "sha256:..." } ],
"requested_by": { "iss": "...", "sub": "..." },
"deleted_at": "YYYY-MM-DDTHH:MM:SSZ",
"retention_policy_version": "pii-retention-v1"
}
}
```
Signiert vom PII-Mediator-Adapter (`agent_id = "pii-mediator"`), landet im Transparency Log.
## Begründung
- **1 Jahr trifft den Sweet Spot.** Länger als ein interner Audit-Zyklus (meist quartalsweise); kurz genug, dass wir nicht in GoBD-Territorium rutschen; akzeptabel für Betroffene (vgl. gängige SaaS-Retention bei Log-Daten).
- **Pro-Typ-Konfigurierbarkeit** erlaubt es, z.B. Debugging-Workflows auf 30 Tage und besonders sensible Workflows auf das Minimum zu drücken.
- **Deletion-Attestierung** schließt die Nachweislücke „zu diesem Workflow waren PII-Daten vorhanden und wurden am X auf Antrag Y gelöscht". Ohne diese Attestierung wäre Löschen und Nichthaben nachträglich nicht unterscheidbar.
- **Automatische Löschung über Cron**, nicht erst auf Zugriff — damit garantieren wir, dass PII tatsächlich verschwindet und nicht erst durch Zufall irgendwann einmal.
## Konsequenzen
### Positive
- DSGVO-Anfragen können technisch binnen Minuten abgearbeitet werden (vorzeitiger `DELETE`).
- Datenwachstum im PII-Store ist bounded.
- Deletion-Nachweis selbst ist kryptografisch (nicht nur Audit-Log).
### Negative / Trade-offs
- Fehlbedienung oder Scheduler-Bug kann Daten einen Tag zu früh löschen — Verification-Antworten dieser Workflows werden dann `content_check: "pii_purged"`. Mitigation: Dry-Run-Modus im Sweeper mit Warnung an Operator, bevor der echte Lauf greift.
- OpenBao-Transit-Key-Vergessen ist unwiderruflich — Backup-Strategie muss sicherstellen, dass vergessene Keys nicht aus einem alten Backup zurückkehren. Siehe Folgearbeit.
### Folgearbeiten / Open Points
- Policy für Backup-Rotation: OpenBao-Snapshots dürfen nicht länger als `retention_days + 7` aufgehoben werden, damit vergessene Keys nicht wiederauftauchen.
- Datenschutz-Dokument (für Benutzer-Information und AV-Vertrag) muss die 1-Jahres-Retention explizit benennen.
- Monitoring: tägliche Metrik für Anzahl gelöschter Workflows + Alert, wenn Sweeper nicht läuft.
## Links
- `docs/architecture/v1.1.md` Abschnitte 8.1, 8.2, 8.4
- DSGVO Art. 17
- OpenBao Transit docs (Key Rotation + Delete)