Kochbuch · ISO/IEC TS 27560:2023 Data Agreements + Einwilligungs-Belege

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.

Was Sie bekommen.
  • 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).

ZweckMethodeURLAuth
DA anlegenPOST/oidc.ashx?action=da-createAdmin-Bearer o. HMAC
DA lesenGET/oidc.ashx?action=da-read&da_id=…Admin-Bearer o. HMAC
DA aktualisieren (neue Revision)POST/oidc.ashx?action=da-updateAdmin-Bearer o. HMAC
DA löschenPOST/oidc.ashx?action=da-deleteAdmin-Bearer o. HMAC
DA auflistenGET/oidc.ashx?action=da-listAdmin-Bearer o. HMAC
Revisionen auflistenGET/oidc.ashx?action=da-list-revisions&da_id=…Admin-Bearer o. HMAC
Beleg signierenPOST/oidc.ashx?action=receipt-signSubjekt-Bearer (o. Admin)
Beleg widerrufenPOST/oidc.ashx?action=receipt-revokeSubjekt-Bearer (o. Admin)
Meine Belege auflistenGET/oidc.ashx?action=receipt-listSubjekt-Bearer
Meine Zugriffshistorie lesenGET/oidc.ashx?action=access-logSubjekt-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" }
Admins können im Namen einer Person signieren, indem sie "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-revoke aufruft.
  • 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.deleted
  • consent.receipt.signed / consent.receipt.revoked
  • consent.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:

Standards: ISO/IEC TS 27560:2023 (Struktur von Einwilligungsdatensätzen) · DSGVO Art. 15, 17, 21 · European Digital Identity Wallet ARF 3.0 §5.11 · OpenID Connect Core 1.0 für Bearer-Transport · RFC 9116 für Discovery des DSB-Kontakts über security.txt. Fehler melden an info@aloaha.com.