Ein versioniertes Data Agreement veröffentlichen. Signierten Beleg sammeln. Betroffene einsehen und widerrufen lassen.
Aufsichtsbehörden fragen zunehmend nach maschinenlesbaren Einwilligungs-Belegen, die auf ein versioniertes Data Agreement referenzieren — nicht nur nach einer "Ich stimme zu"-Zeile im Log. ISO/IEC TS 27560:2023 definiert die Struktur. CodeB liefert Speicher und Endpunkte; dieses Kochbuch bindet sie in einem Nachmittag in Ihre eigene Anwendung ein. Es ergänzt die bereits veröffentlichte DSFA und das Verzeichnis von Verarbeitungstätigkeiten und gibt jeder Person über das Datenschutz-Dashboard eine erstklassige Sicht auf die eigene Einwilligungs-Historie.
- Ein versioniertes Data-Agreement-Objekt pro (Tenant, Zweck). CRUD + Revisionshistorie + Löschen.
- Signierte Einwilligungs-Belege pro Person mit Opt-in/Opt-out und Widerrufspfad.
- Subjektbezogene Zugriffshistorie — jedes Ereignis, das den Datensatz berührt hat.
- Betroffenenseitige Oberfläche
privacy-dashboard.html, die alles anzeigt und Aktionen ermöglicht. - ARF-3.0-Konformitätsseite bekommt Kategorie §5.11 Einwilligungs-Lebenszyklus & Betroffenenrechte, mit "Erfüllt" gekennzeichnet.
0 Warum das existiert
Verzeichnis von Verarbeitungstätigkeiten (VVT) und DSFA beschreiben, was ein Verantwortlicher mit personenbezogenen Daten tut. Was sie nicht tun: einen pro Person und Zweck revisionsgebundenen Beleg erzeugen, den eine betroffene Person abrufen, herunterladen und widerrufen kann. Das ISO/IEC-TS-27560:2023-Data-Agreement-Objekt wurde geschrieben, um genau diese Lücke zu schließen. Die European-Digital-Identity-Wallet-Architektur-Referenzframework-Version 3.0 fasst denselben Gedanken in §5.11 Einwilligungs-Lebenszyklus & Betroffenenrechte: Anbieter sollen einen Speicher erster Klasse, Widerruf und maschinenlesbaren Export bereitstellen.
CodeB implementiert alles in /oidc.ashx, mit flachem JSON unter App_Data/<tenant>/ im Hintergrund. Keine Datenbank. Atomare Schreibvorgänge mit .backup. Tenant-Isolation. Rate-limitierte Eintrittspunkte. Jeder Endpunkt gibt eine [CONSENT-*-DIAG]-Trace-Zeile aus.
1 Endpunkt-Oberfläche
Ersetzen Sie <HOST> durch Ihren CodeB-Tenant-Hostnamen (z.B. www.aloaha.com).
| Zweck | Methode | URL | Auth |
|---|---|---|---|
| DA anlegen | POST | /oidc.ashx?action=da-create | Admin-Bearer o. HMAC |
| DA lesen | GET | /oidc.ashx?action=da-read&da_id=… | Admin-Bearer o. HMAC |
| DA aktualisieren (neue Revision) | POST | /oidc.ashx?action=da-update | Admin-Bearer o. HMAC |
| DA löschen | POST | /oidc.ashx?action=da-delete | Admin-Bearer o. HMAC |
| DA auflisten | GET | /oidc.ashx?action=da-list | Admin-Bearer o. HMAC |
| Revisionen auflisten | GET | /oidc.ashx?action=da-list-revisions&da_id=… | Admin-Bearer o. HMAC |
| Beleg signieren | POST | /oidc.ashx?action=receipt-sign | Subjekt-Bearer (o. Admin) |
| Beleg widerrufen | POST | /oidc.ashx?action=receipt-revoke | Subjekt-Bearer (o. Admin) |
| Meine Belege auflisten | GET | /oidc.ashx?action=receipt-list | Subjekt-Bearer |
| Meine Zugriffshistorie lesen | GET | /oidc.ashx?action=access-log | Subjekt-Bearer |
Jeder Endpunkt wird im OIDC-Discovery-Dokument unter den herstellerspezifischen Schlüsseln data_agreement_endpoint, consent_receipt_endpoint, consent_receipt_list_endpoint, subject_access_log_endpoint beworben.
2 Admin-Bearer-Token besorgen
Jeder Admin-Endpunkt akzeptiert entweder ein Bearer-JWT mit role in {admin, superuser} oder einen X-CodeB-Admin-Signature-HMAC über den festen Bucket-String (wie TS7/TS8):
curl -s -u '$CLIENT_ID:$CLIENT_SECRET' \
-H 'Accept: application/json' \
-d 'grant_type=client_credentials&scope=admin' \
https://<HOST>/oidc.ashx?action=token
# => { "access_token": "eyJ...", "token_type":"Bearer", "expires_in":900 }
export ADMIN_TOKEN=eyJ...
3 Data Agreement anlegen
Die Felder purpose und lawful_basis sind Pflicht. Alle anderen sind optional, aber für Audits empfohlen.
curl -s -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
https://<HOST>/oidc.ashx?action=da-create \
-d '{
"purpose": "Marketing-Analyse Anmelde-Funnel (aggregiert)",
"lawful_basis": "consent",
"controller": "Aloaha Limited, Malta",
"controller_contact": "dpo@aloaha.com",
"retention_days": 90,
"data_categories": ["email", "signup_ts", "utm_source"],
"third_parties": [],
"cross_border_transfers": false,
"policy_url": "https://<HOST>/de/privacy.html",
"withdrawal_url": "https://<HOST>/de/privacy-dashboard.html",
"language": "de"
}'
# => { "ok": true, "da_id": "3f9a2b7e10c4d55e", "rev": 1 }
4 Update — neue Revision anhängen
Updates ändern bestehende Revisionen nie. Sie hängen eine neue Revision mit monoton wachsender rev-Nummer an. Bereits signierte Belege bleiben an ihre älteren Revisionen gebunden.
curl -s -X POST -H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
https://<HOST>/oidc.ashx?action=da-update \
-d '{
"da_id": "3f9a2b7e10c4d55e",
"patch": {
"retention_days": 60,
"third_parties": ["Aggregated Analytics BV"]
}
}'
# => { "ok": true, "da_id": "3f9a2b7e10c4d55e", "rev": 2 }
5 DAs + Revisionen auflisten
# Alle DAs des Tenants (max. 5000). curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ https://<HOST>/oidc.ashx?action=da-list # Alle Revisionen eines DA (max. 200). curl -s -H "Authorization: Bearer $ADMIN_TOKEN" \ "https://<HOST>/oidc.ashx?action=da-list-revisions&da_id=3f9a2b7e10c4d55e"
6 Einwilligungs-Beleg signieren
Das ist der betroffenenseitige Aufruf. Die Person meldet sich zuerst an Ihrem OIDC-Provider an, erhält ihr eigenes Access-Token und schickt dann den receipt-sign-Aufruf. Der Server legt einen Beleg unter SHA-256(sub) ab und fügt der Zugriffshistorie einen Eintrag hinzu.
// Aus dem Browser nach der Anmeldung:
await fetch('/oidc.ashx?action=receipt-sign', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + userAccessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
da_id: '3f9a2b7e10c4d55e',
opt_in: true
})
});
// => 201 { "ok": true, "receipt_id": "9c11...", "da_id": "3f9a2b7e10c4d55e" }
"sub": "<Subjekt-Kennung>" in den Body aufnehmen. Nicht-Admin-Aufrufer können das nicht: der Server verwendet immer die eigene sub des Bearers.7 Beleg widerrufen
Widerruf löscht nicht. Der Beleg bleibt als Audit-Spur mit revoked_at gesetzt und opt_in auf false umgeschaltet.
await fetch('/oidc.ashx?action=receipt-revoke', {
method: 'POST',
headers: {
'Authorization': 'Bearer ' + userAccessToken,
'Content-Type': 'application/json'
},
body: JSON.stringify({
da_id: '3f9a2b7e10c4d55e',
receipt_id: '9c11...'
})
});
// => 200 { "ok": true, "receipt_id": "9c11...", "da_id": "3f9a2b7e10c4d55e" }
8 Datenschutz-Dashboard
Sie müssen keine UI bauen. Verlinken Sie /de/privacy-dashboard.html von Ihrer Kontoseite. Das Dashboard:
- Liest Belege und Zugriffshistorie der Person mit deren eigenem Bearer-Token.
- Rendert jeden Beleg mit DA-ID, Revision, Opt-in-Status, Signatur/Widerruf-Zeitstempel und Download-Knopf.
- Bietet einen Widerrufsknopf pro Zeile, der
?action=receipt-revokeaufruft. - Bietet einen prominenten Vollständige Löschung anfordern-Knopf, der eine ARF-TS7-Art.-17-Anfrage über
?action=data-deletion-requestöffnet.
Die englische Fassung liegt unter /privacy-dashboard.html. Das Dashboard ist vollständig eigenständig — eine HTML-Datei, kein Build-Schritt, kein Framework, kein externes CDN.
9 Der Art.-17-Löschpfad
Einwilligungswiderruf ist nicht das Gleiche wie Löschung. Wenn eine Person jede Spur ihres Kontos entfernt sehen möchte, öffnet das Dashboard eine gequeuete Löschanfrage gegen den bestehenden ?action=data-deletion-request-Endpunkt (ARF TS7). Ein menschlicher Operator arbeitet die Warteschlange über ?action=data-deletion-list ab. Das ARF-3.0-Zielfenster für die Abarbeitung sind 30 Tage.
Der Endpunkt ist auf 3 Anfragen pro Stunde je IP begrenzt, kontaktvalidiert (nur E-Mail oder https-URL) und body-begrenzt auf 4 KB — sicher öffentlich zugänglich.
10 Metriken + Abrechnung
Jedes Einwilligungs-Lebenszyklus-Ereignis gibt eine [METRIC]-Zeile aus, die in die Standard-Nutzungserfassung fließt. Reservierte Metriknamen:
consent.da.created/consent.da.updated/consent.da.deletedconsent.receipt.signed/consent.receipt.revokedconsent.access.read
11 Audit + Überprüfung
Die ARF-3.0-Konformitätsseite trägt eine Kategorie §5.11 Einwilligungs-Lebenszyklus & Betroffenenrechte. Zeilen: Data-Agreement-Speicher + Revisionen (Erfüllt), signierte Einwilligungs-Belege (Erfüllt), subjektbezogene Zugriffshistorie (Erfüllt), Datenschutz-Dashboard (Erfüllt). Verifikationszeiger: dieses Kochbuch + /de/privacy-dashboard.html.
Verwandte Dokumente: