fix(mail/oauth): add email OIDC scope — id_token Email-Claim für Personal-Accounts

Microsoft Personal-Accounts (outlook.com, hotmail.com, live.com) liefern mit
`openid` allein keinen `email`-Claim ins ID-Token. `preferred_username` ist
ein Display-Identifier, oft die Login-Email — aber nicht garantiert. Bei
manchen Account-Konfigurationen ist der Claim leer oder enthält einen MS-
internen Identifier.

Fix: `email` als zusätzlichen OIDC-Standard-Scope. `email` ist ein "identity
scope" (wie openid/profile/offline_access) und damit per OIDC-Spezifikation
mit jedem Resource-Scope (auch IMAP.AccessAsUser.All) kompatibel — verursacht
KEIN AADSTS70011 mehr.

Azure-App-Permissions müssen nicht angepasst werden — OIDC-Identity-Scopes
brauchen keine explizite Admin-Permission-Grant.

extractEmailFromIdToken bleibt unverändert — die Lookup-Order `email →
preferred_username → upn` greift jetzt erstmal auf den frischen `email`-Claim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
chahinebrini 2026-05-13 22:21:31 +02:00
parent 09d85180b6
commit cb5c193980
2 changed files with 16 additions and 7 deletions

View File

@ -2,10 +2,12 @@
**An:** Chahine Brini (Geschäftsführung, Rebreak) **An:** Chahine Brini (Geschäftsführung, Rebreak)
**Von:** Hans Müller, externer Datenschutzbeauftragter **Von:** Hans Müller, externer Datenschutzbeauftragter
**Datum:** 2026-05-13 **Datum:** 2026-05-13 (Korrektur-Revision nach Live-Test, selber Tag)
**Betreff:** DSGVO-Review Outlook-IMAP-OAuth-Integration (Mail-Auto-Delete-Feature) **Betreff:** DSGVO-Review Outlook-IMAP-OAuth-Integration (Mail-Auto-Delete-Feature)
**Klassifikation:** Internes Compliance-Memo, kein Rechtsrat **Klassifikation:** Internes Compliance-Memo, kein Rechtsrat
> **Revisions-Hinweis (2026-05-13, Abend):** Beim Live-Test hat sich gezeigt, dass Microsofts v2.0-Token-Endpoint Multi-Resource-Scopes nicht zulässt (`AADSTS70011`). Der Scope `User.Read` (Microsoft Graph) ist nicht im selben Token-Exchange mit `IMAP.AccessAsUser.All` (Outlook-Resource) kombinierbar und musste **entfernt** werden. Sections 1, 3.1, 4.1 und 9 wurden entsprechend angepasst. Die Identifikation der verbundenen Mailbox erfolgt jetzt ausschließlich über `id_token.preferred_username` (Scope `openid`) — d.h. nur noch die E-Mail-Adresse, kein Display-Name, kein Foto, keine Profil-Daten.
--- ---
## 1. Gesamteinschätzung (Executive Summary) ## 1. Gesamteinschätzung (Executive Summary)
@ -13,6 +15,7 @@
**Risiko-Klasse: Mittel** — vorausgesetzt, die unten genannten Pflichten werden vor Live-Schaltung erledigt. **Risiko-Klasse: Mittel** — vorausgesetzt, die unten genannten Pflichten werden vor Live-Schaltung erledigt.
- Die OAuth2-Integration ist datenschutzrechtlich **günstiger als die bisherige App-Passwort-Lösung** (granular widerrufbare Scopes, Token-Rotation, kein Klartext-Credential bei Rebreak). - Die OAuth2-Integration ist datenschutzrechtlich **günstiger als die bisherige App-Passwort-Lösung** (granular widerrufbare Scopes, Token-Rotation, kein Klartext-Credential bei Rebreak).
- **Datenminimierung technisch erzwungen:** Nach Live-Test-Korrektur reduziert sich der Scope-Umfang auf das absolute Minimum — `IMAP.AccessAsUser.All` + `offline_access` + `openid`. Es werden keinerlei Profil-Daten (Display-Name, Foto, Kontakte, Kalender, Job-Titel) aus dem Microsoft-Konto gelesen. Die Anzeige der Verbindung in der App erfolgt über einen vom User selbst vergebenen Titel und die E-Mail-Adresse — siehe Section 4.1.
- Microsoft ist als Auftragsverarbeiter für Exchange Online seit Februar 2025 vollständig im **EU Data Boundary** — der Drittland-Transfer ist damit deutlich entschärft, aber **nicht vollständig eliminiert** (Support-Zugriffe, Telemetrie, Identity-Platform-Subsysteme können noch US-Routing enthalten). - Microsoft ist als Auftragsverarbeiter für Exchange Online seit Februar 2025 vollständig im **EU Data Boundary** — der Drittland-Transfer ist damit deutlich entschärft, aber **nicht vollständig eliminiert** (Support-Zugriffe, Telemetrie, Identity-Platform-Subsysteme können noch US-Routing enthalten).
- Microsofts Standard-**DPA** (Stand September 2025) erfüllt die Art. 28-Anforderungen formal — eine eigenständige Vertragsunterzeichnung ist für Consumer-/Free-Tier-OAuth in der Regel **nicht möglich**; die DPA gilt qua Akzeptanz der Microsoft Services Agreement bzw. App-Registration-Bedingungen. Dies sollten Sie einmal anwaltlich verifizieren lassen, da Rebreak hier als „Partner" und nicht als zahlender M365-Tenant agiert. - Microsofts Standard-**DPA** (Stand September 2025) erfüllt die Art. 28-Anforderungen formal — eine eigenständige Vertragsunterzeichnung ist für Consumer-/Free-Tier-OAuth in der Regel **nicht möglich**; die DPA gilt qua Akzeptanz der Microsoft Services Agreement bzw. App-Registration-Bedingungen. Dies sollten Sie einmal anwaltlich verifizieren lassen, da Rebreak hier als „Partner" und nicht als zahlender M365-Tenant agiert.
- **Kein Blocker** für Go-Live, aber Pflicht-Aufgaben (VVT, Datenschutzerklärung, User-Einwilligungstext, vollständige DB-seitige Token-Löschung + User-Information zum manuellen Entfernen unter `account.microsoft.com`, siehe Section 5.1) **vor** Aktivierung. - **Kein Blocker** für Go-Live, aber Pflicht-Aufgaben (VVT, Datenschutzerklärung, User-Einwilligungstext, vollständige DB-seitige Token-Löschung + User-Information zum manuellen Entfernen unter `account.microsoft.com`, siehe Section 5.1) **vor** Aktivierung.
@ -68,13 +71,13 @@ Microsofts „[Products and Services Data Protection Addendum (DPA)](https://aka
| **Zweck** | Erkennung und Löschung von Glücksspiel-Werbemails im Nutzer-Postfach (Sucht-Trigger-Minimierung) | | **Zweck** | Erkennung und Löschung von Glücksspiel-Werbemails im Nutzer-Postfach (Sucht-Trigger-Minimierung) |
| **Rechtsgrundlage** | Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) i.V.m. Art. 9 Abs. 2 lit. a DSGVO (ausdrückliche Einwilligung) — Wechsel auf Art. 9 Abs. 2 lit. h bei DiGA-Listung | | **Rechtsgrundlage** | Art. 6 Abs. 1 lit. b DSGVO (Vertragserfüllung) i.V.m. Art. 9 Abs. 2 lit. a DSGVO (ausdrückliche Einwilligung) — Wechsel auf Art. 9 Abs. 2 lit. h bei DiGA-Listung |
| **Betroffene Personen** | Registrierte Rebreak-Nutzer mit Microsoft-Consumer-Postfach (outlook.com, hotmail.com, live.com, msn.com) | | **Betroffene Personen** | Registrierte Rebreak-Nutzer mit Microsoft-Consumer-Postfach (outlook.com, hotmail.com, live.com, msn.com) |
| **Datenkategorien (Art. 6)** | E-Mail-Adresse des Microsoft-Kontos, Display-Name des Microsoft-Kontos, OAuth-Access-Token, OAuth-Refresh-Token, Token-Ablaufdatum, technische Verbindungs-Metadaten (IMAP-Session-Logs) | | **Datenkategorien (Art. 6)** | E-Mail-Adresse des Microsoft-Kontos (aus `id_token.preferred_username`, Scope `openid`), OAuth-Access-Token, OAuth-Refresh-Token, Token-Ablaufdatum, technische Verbindungs-Metadaten (IMAP-Session-Logs), vom User selbst vergebener Anzeige-Titel der Verbindung (App-lokales Anonymitäts-Pattern, kein MS-Datum) |
| **Datenkategorien (Art. 9)** | Indirekt: Verbindung „MS-Account-Inhaber X nutzt Anti-Glücksspiel-App" → Rückschluss auf Suchterkrankung möglich (siehe Abschnitt 6) | | **Datenkategorien (Art. 9)** | Indirekt: Verbindung „MS-Account-Inhaber X nutzt Anti-Glücksspiel-App" → Rückschluss auf Suchterkrankung möglich (siehe Abschnitt 6) |
| **Empfänger / Sub-AV** | Microsoft Ireland Operations Ltd., One Microsoft Place, South County Business Park, Leopardstown, Dublin 18, Irland | | **Empfänger / Sub-AV** | Microsoft Ireland Operations Ltd., One Microsoft Place, South County Business Park, Leopardstown, Dublin 18, Irland |
| **Drittland-Transfer** | Primär EU (EU Data Boundary, Exchange Online), residuale Transfers in USA für Identity-Platform/Support (SCCs 2021/914 + EU-US DPF) | | **Drittland-Transfer** | Primär EU (EU Data Boundary, Exchange Online), residuale Transfers in USA für Identity-Platform/Support (SCCs 2021/914 + EU-US DPF) |
| **Speicherdauer** | Tokens: bis User-Disconnect oder 90 Tage Inaktivität (refresh-token-TTL); Verbindungs-Logs: 30 Tage rolling | | **Speicherdauer** | Tokens: bis User-Disconnect oder 90 Tage Inaktivität (refresh-token-TTL); Verbindungs-Logs: 30 Tage rolling |
| **TOMs** | AES-256-Encryption-at-rest für Tokens, TLS 1.2+ in Transit, Zugriff auf Token-Tabelle nur durch Backend-Service-Account, Hetzner DE Hosting | | **TOMs** | AES-256-Encryption-at-rest für Tokens, TLS 1.2+ in Transit, Zugriff auf Token-Tabelle nur durch Backend-Service-Account, Hetzner DE Hosting |
| **Löschkonzept** | Bei User-Disconnect oder Account-Löschung: vollständige Löschung aller Token-/Profil-Daten aus der Rebreak-DB. Microsoft stellt keinen Drittanbieter-Token-Revoke-Endpoint bereit (siehe Section 5.1) — daher zusätzlich User-Information mit Anleitung zum manuellen Entfernen unter `account.microsoft.com → Sicherheit → Berechtigungen für Apps`. | | **Löschkonzept** | Bei User-Disconnect oder Account-Löschung: vollständige Löschung aller Token-Daten, der gespeicherten E-Mail-Adresse und des User-Titels aus der Rebreak-DB. Microsoft stellt keinen Drittanbieter-Token-Revoke-Endpoint bereit (siehe Section 5.1) — daher zusätzlich User-Information mit Anleitung zum manuellen Entfernen unter `account.microsoft.com → Sicherheit → Berechtigungen für Apps`. |
### 3.2 Sub-AV-Liste aktualisieren ### 3.2 Sub-AV-Liste aktualisieren
@ -106,14 +109,13 @@ Microsofts „[Products and Services Data Protection Addendum (DPA)](https://aka
> Diese Tokens berechtigen Rebreak ausschließlich zu folgenden Zugriffen (OAuth-Scopes, nach Prinzip der Datenminimierung): > Diese Tokens berechtigen Rebreak ausschließlich zu folgenden Zugriffen (OAuth-Scopes, nach Prinzip der Datenminimierung):
> - `IMAP.AccessAsUser.All` (Lese-/Lösch-Zugriff auf Ihre E-Mail-Inbox) > - `IMAP.AccessAsUser.All` (Lese-/Lösch-Zugriff auf Ihre E-Mail-Inbox)
> - `offline_access` (technischer Refresh-Token-Bezug) > - `offline_access` (technischer Refresh-Token-Bezug)
> - `openid` (OAuth-Mindesthygiene) > - `openid` (OAuth-Mindesthygiene — liefert Ihre E-Mail-Adresse für die App-Anzeige)
> - `User.Read` (Anzeige Ihres Namens in der Rebreak-App nach Verbindungs-Aufbau)
> >
> Aus Ihrem Microsoft-Konto-Profil lesen wir ausschließlich Ihren angezeigten Namen und Ihre E-Mail-Adresse (Scope `User.Read`), um eine freundliche Anzeige der verbundenen Verbindung in der App zu ermöglichen („Verbunden als …"). Keine weiteren Profil-Daten wie Kontakte, Kalender, Fotos, Telefonnummer, Job-Titel oder Manager-Informationen werden gelesen — auch wenn der Scope `User.Read` dies technisch erlauben würde. Wir wenden hier das Prinzip der Datenminimierung (Art. 5 Abs. 1 lit. c DSGVO) durch eine **technische Selbstbeschränkung im Client-Code** an. > Wir lesen **keine** weiteren Daten: keinen Display-Namen, kein Foto, keine Kontakte, keine Kalender, keine Profil-Daten. Aus dem von Microsoft im Rahmen des OAuth-Flows ausgestellten Identitäts-Token (`id_token`) übernehmen wir lediglich Ihre E-Mail-Adresse (`preferred_username`), um die Verbindung in Ihrer App-Übersicht zuordenbar zu machen. Zusätzlich können Sie selbst einen freundlichen Titel für die Verbindung vergeben (z.B. „Privat" oder „Arbeit"); dieser Titel wird nur lokal in Ihrem Rebreak-Konto gespeichert und nie an Microsoft übermittelt.
> >
> Sub-Auftragsverarbeiter ist Microsoft Ireland Operations Ltd. (Dublin, Irland). Die Postfach-Verarbeitung erfolgt innerhalb des Microsoft EU Data Boundary (EU/EFTA). In Einzelfällen (Identity-Platform, Support) können Restdaten in die USA übermittelt werden — abgesichert durch die EU-Standardvertragsklauseln (Modul 2/3) und das EU-US Data Privacy Framework. > Sub-Auftragsverarbeiter ist Microsoft Ireland Operations Ltd. (Dublin, Irland). Die Postfach-Verarbeitung erfolgt innerhalb des Microsoft EU Data Boundary (EU/EFTA). In Einzelfällen (Identity-Platform, Support) können Restdaten in die USA übermittelt werden — abgesichert durch die EU-Standardvertragsklauseln (Modul 2/3) und das EU-US Data Privacy Framework.
> >
> Sie können diese Verbindung jederzeit in den Rebreak-Einstellungen trennen. Wir löschen in diesem Fall alle bei uns gespeicherten Tokens und Profil-Daten vollständig aus unserer Datenbank. Microsoft stellt Drittanbieter-Apps technisch keinen Token-Widerruf-Endpoint zur Verfügung — für eine **vollständige** Entfernung der Rebreak-Berechtigung in Ihrem Microsoft-Konto empfehlen wir Ihnen daher, zusätzlich unter `account.microsoft.com → Sicherheit → Berechtigungen für Apps` die App „Rebreak" zu entfernen. Wir blenden Ihnen direkt nach dem Trennen in der App eine Schritt-für-Schritt-Anleitung dazu ein. > Sie können diese Verbindung jederzeit in den Rebreak-Einstellungen trennen. Wir löschen in diesem Fall alle bei uns gespeicherten Tokens, die E-Mail-Adresse und den von Ihnen vergebenen Verbindungs-Titel vollständig aus unserer Datenbank. Microsoft stellt Drittanbieter-Apps technisch keinen Token-Widerruf-Endpoint zur Verfügung — für eine **vollständige** Entfernung der Rebreak-Berechtigung in Ihrem Microsoft-Konto empfehlen wir Ihnen daher, zusätzlich unter `account.microsoft.com → Sicherheit → Berechtigungen für Apps` die App „Rebreak" zu entfernen. Wir blenden Ihnen direkt nach dem Trennen in der App eine Schritt-für-Schritt-Anleitung dazu ein.
### 4.2 Unterschied „OAuth-Token-Storage vs App-Passwort-Storage" ### 4.2 Unterschied „OAuth-Token-Storage vs App-Passwort-Storage"
@ -220,6 +222,7 @@ Wenn ein User im OAuth-Consent-Screen liest „Rebreak (Anti-Glücksspiel-App) m
3. **Finaler Wortlaut der Datenschutzerklärungs-Änderungen** — Ich liefere DSB-Vorlagen, die juristische Abnahme bleibt Anwalt. 3. **Finaler Wortlaut der Datenschutzerklärungs-Änderungen** — Ich liefere DSB-Vorlagen, die juristische Abnahme bleibt Anwalt.
4. **AGB-Anpassung** für das veränderte Verfahren (App-Passwort → OAuth). 4. **AGB-Anpassung** für das veränderte Verfahren (App-Passwort → OAuth).
5. **Art. 17-Erfüllung trotz fehlendem MS-Revoke-Endpoint** (siehe Section 5.1) — konkret: Erfüllt die in-app User-Information mit Anleitung zum manuellen Entfernen unter `account.microsoft.com` die Art. 17-Pflicht ausreichend, oder müssen wir zusätzlich z. B. eine E-Mail-Erinnerung nach X Tagen versenden, bzw. eine schriftliche Bestätigung der erfolgten Entfernung anfordern? Hier wäre auch eine kurze Einschätzung wertvoll, ob die fehlende technische Revoke-Möglichkeit als Haftungs-Risiko für Rebreak einzustufen ist oder als „auf Seite des Identity Providers liegend" akzeptiert wird. 5. **Art. 17-Erfüllung trotz fehlendem MS-Revoke-Endpoint** (siehe Section 5.1) — konkret: Erfüllt die in-app User-Information mit Anleitung zum manuellen Entfernen unter `account.microsoft.com` die Art. 17-Pflicht ausreichend, oder müssen wir zusätzlich z. B. eine E-Mail-Erinnerung nach X Tagen versenden, bzw. eine schriftliche Bestätigung der erfolgten Entfernung anfordern? Hier wäre auch eine kurze Einschätzung wertvoll, ob die fehlende technische Revoke-Möglichkeit als Haftungs-Risiko für Rebreak einzustufen ist oder als „auf Seite des Identity Providers liegend" akzeptiert wird.
6. **Wegfall `User.Read` infolge MS-V2-Token-Endpoint-Limitation (Multi-Resource):** Das ursprüngliche Argument, mit `User.Read` einen Display-Namen aus dem Microsoft-Konto für ein freundliches Anonymitäts-Pattern in der App zu nutzen, ist mit dem Live-Test-Fix obsolet — Microsoft erlaubt im selben Token-Exchange keine Scopes mehrerer Resources (Graph + Outlook), die App kann den Display-Namen technisch nicht mehr abrufen. Der von Rebreak heute ausgelieferte `ConnectMailSheet` bietet stattdessen einen user-eingebbaren Verbindungs-Titel, womit das Anonymitäts-Pattern App-seitig erfüllt ist (und sogar datenschutzfreundlicher, weil der User die Anzeige selbst wählt statt Rebreak ein MS-Profil-Datum spiegelt). **Falls** in einer späteren Produkt-Version aus Datenschutz- oder UX-Sicht doch wieder ein Display-Name aus dem Microsoft-Konto gewünscht wird, müsste ein **separater Microsoft-Graph-Token-Exchange** (eigener `/token`-Aufruf, ausschließlich mit `User.Read`-Scope, zusätzlicher Refresh-Token) implementiert werden. Das wäre kein Implementierungs-Detail mehr, sondern: zusätzlicher Token-Speicher, zusätzlicher Drittland-/Sub-AV-Aspekt (Graph-API-Endpoint), eigene VVT-Zeile, eigener Scope-Eintrag in der Datenschutzerklärung — und damit ein **neuer DSB-Review-Punkt** vor Aktivierung.
--- ---

View File

@ -33,6 +33,12 @@ export const MS_OAUTH_SCOPES = [
"https://outlook.office.com/IMAP.AccessAsUser.All", "https://outlook.office.com/IMAP.AccessAsUser.All",
"offline_access", "offline_access",
"openid", "openid",
// Standard-OIDC-Scope: liefert `email`-Claim ins id_token. Microsoft Personal-
// Accounts geben mit `openid` allein keinen Email-Claim raus (preferred_username
// ist Display-Identifier, kein garantiertes Email-Feld). `email` ist ein OIDC-
// "identity scope" und damit per Definition kompatibel mit jeder Resource-API
// — verursacht KEIN AADSTS70011 mit dem IMAP-Scope.
"email",
].join(" "); ].join(" ");
/** /**