DSGVO-Konformität und Datenschutz
Auf dieser Seite
Aktualisiert am 3. November 2026. Die Liste der durch die Kategorie
piierfassten Elemente stimmt nun mit der Definition von Mistral überein (Gesundheitsdaten unterliegen anderen Regeln, und die Kategoriehealthrichtet sich an Anfragen nach medizinischen Ratschlägen). Der zuvor konforme Logger hat sein Ende des Aufbewahrungszeitraums falsch berechnet, was dazu führte, dass Bereinigungsvorgänge alles löschten; zudem verwendete er einen fest codierten Standard-Salzschlüssel für die Pseudonymisierung und die veraltete Funktiondatetime.utcnow(). Die Pseudonymisierung verwendet nun HMAC-SHA-256 mit einem zwingenden Schlüssel. Quellen: Moderation & Guardrailing · DSGVO, Erwägungsgrund 26 und Artikel 4 und 22 · Python hmac.
KI und personenbezogene Daten: Ein strenger Rahmen
Es gibt einen Paradoxon im Kern dieser Lektion, und ein klares Verständnis desselben vermeidet viele Designfehler: Ihr Moderationssystem ist selbst eine Verarbeitung personenbezogener Daten. Um Ihre Nutzer zu schützen, analysieren Sie deren Texte, generieren Sie Bewertungen und speichern Sie Protokolle – alles Operationen, die die DSGVO genau wie jede andere Verarbeitungstätigkeit regelt.
Konformität bedeutet daher nicht, eine Schutzschicht über das Moderationssystem zu legen. Es bedeutet, das Moderationssystem selbst so zu gestalten, dass es die minimale Datenmenge verarbeitet, für den kürzest möglichen Zeitraum, während gleichzeitig ein Nachweis seiner Entscheidungen geführt wird. Dies ist das rote Faden, der durch die folgenden Abschnitte führt.
Die DSGVO (General Data Protection Regulation) gilt vollständig für KI-Anwendungen, die Daten von europäischen Bewohnern verarbeiten. Die Inhaltsmoderation selbst erzeugt Daten, die in den Geltungsbereich der DSGVO fallen. Sie müssen Ihre Verpflichtungen verstehen, um Strafen bis zu 4 % des weltweiten Jahresumsatzes zu vermeiden.
Die Kategorie PII in der Mistral-Moderation
Die Klassifizierung von Mistral in der Kategorie pii erkennt Anfragen oder Enthüllungen personenbezogener Informationen. Ein architektonischer Punkt muss sofort gemacht werden: Dieser Klassifizierer ist ein Sicherheitsnetz, keine Garantie. Er erfasst verschiedene Formulierungen, die ein Regex übersehen würde („meine Nummer ist…”), aber wie jedes Modell weist er auch falsch negative Ergebnisse auf. Umgekehrt erfasst ein Regex zuverlässig strukturierte Formate – IBANs, Sozialversicherungsnummern, Kreditkarten – aber nichts anderes. Best Practice kombiniert beides: Regex für bekannte Formate, Klassifizierer für den Rest. Erfasste Typen umfassen:
- Vollständige Namen
- Adressen
- Telefonnummern
- Sozialversicherungsnummern
- Details zu Finanzkonten
Die Definition von Mistral konzentriert sich auf die Anfrage, das Teilen oder den Versuch, diese identifizierenden Informationen zu erhalten.
from mistralai.client import Mistral
import os
import re
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
def detect_pii(text: str) -> dict:
"""Erkennt personenbezogene Daten im Text."""
# Ebene 1: Mistral-Klassifizierer
response = client.classifiers.moderate(
model="mistral-moderation-2603",
inputs=[text]
)
pii_score = (response.results[0].category_scores or {}).get("pii", 0)
# Ebene 2: Regex für gängige Muster
pii_patterns = {
"email": r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
"telephone_fr": r"(?:0|\+33)[1-9](?:\d{2}){4}",
"secu_sociale": r"\d{13,15}",
"carte_bancaire": r"\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}",
"iban": r"FR\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{3}"
}
detected_pii = {}
for name, pattern in pii_patterns.items():
matches = re.findall(pattern, text)
if matches:
detected_pii[name] = len(matches)
return {
"score_classifieur": round(pii_score, 3),
"pii_regex": detected_pii,
"contient_pii": pii_score > 0.2 or len(detected_pii) > 0
}
Anonymisierung vor der Verarbeitung
Die Anonymisierung im Vorfeld ist die kosteneffektivste Maßnahme in dieser gesamten Lektion, da sie die Natur des Problems ändert: Daten, die Ihre Infrastruktur nie verlassen, werfen keine Übertragungsprobleme auf. Das Ersetzen von Namen, E-Mails und Nummern durch Token ([PERSON_1], [EMAIL_1]) vor dem Aufruf des Modells bewahrt fast immer die Bedeutung für die Analyse – und wenn Sie die Zuordnungstabelle lokal behalten, können Sie die echten Werte in die Antwort wieder einfügen. Solange diese Tabelle existiert, handelt es sich rechtlich um Pseudonymisierung, nicht um Anonymisierung: Die Daten bleiben personenbezogen, aber die an das Modell gesendeten Daten erlauben allein keine Identifizierung der Person.
def anonymize_text(text: str) -> tuple:
"""Anonymisiert Text und behält eine Wiederherstellungszuordnung bei."""
mapping = {}
anonymized_text = text
# Anonymisieren von E-Mails
emails = re.findall(
r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}",
text
)
for i, email in enumerate(set(emails)):
placeholder = f"[EMAIL_{i+1}]"
mapping[placeholder] = email
anonymized_text = anonymized_text.replace(email, placeholder)
# Anonymisieren von Telefonnummern
phones = re.findall(
r"(?:0|\+33)[1-9](?:[\s.-]?\d{2}){4}",
text
)
for i, tel in enumerate(set(phones)):
placeholder = f"[TEL_{i+1}]"
mapping[placeholder] = tel
anonymized_text = anonymized_text.replace(tel, placeholder)
# Anonymisieren von Namen (wenn von einem upstream NER erkannt)
# Fügen Sie Ihre eigene NER-Logik hier ein
return anonymized_text, mapping
def restore_text(anonymized_text: str, mapping: dict) -> str:
"""Stellt anonymisierte Daten nach der Verarbeitung wieder her."""
restored_text = anonymized_text
for placeholder, value in mapping.items():
restored_text = restored_text.replace(placeholder, value)
return restored_text
# Verwendung in der Pipeline
original_text = "Contactez [email protected] au 06 12 34 56 78"
anonymized_text, mapping = anonymize_text(original_text)
# → "Contactez [EMAIL_1] au [TEL_1]"
# Anonymisierten Text an das Modell senden
response = client.chat.complete(
model="mistral-large-latest",
messages=[{"role": "user", "content": anonymized_text}]
)
DSGVO-konforme Moderationsprotokolle
Protokolle sind der klassische Blindflecken: Wir denken „personenbezogene Daten” bezüglich Nutzer-Nachrichten, aber selten bezüglich der technischen Spuren, die sie kopieren. Dennoch ist ein Moderationsprotokoll, das den analysierten Text speichert, eine personenbezogene Datenbank mit allen daraus resultierenden Verpflichtungen. Die Faustregel: Speichern Sie Text nur für blockierte Inhalte – Sie werden ihn im Streitfall benötigen – und speichern Sie nur Bewertungen für akzeptierte Inhalte.
import hashlib
import hmac
from datetime import datetime, timedelta, timezone
class LogModerationRGPD:
"""DSGVO-konformer Moderationslogger."""
def __init__(self, retention_jours: int = 90):
self.retention_jours = retention_jours
# Zwingender geheimer Schlüssel, außerhalb des Codes gehalten (Vault oder Umgebungsvariable)
self.key = os.environ["PII_HMAC_KEY"].encode()
def _pseudonymiser(self, user_id: str) -> str:
"""Pseudonymisiert einen Benutzerkennzeichner (HMAC-SHA-256)."""
return hmac.new(self.key, user_id.encode(), hashlib.sha256).hexdigest()[:16]
def log_moderation(self, user_id: str, scores: dict, decision: str,
text: str | None = None) -> dict:
"""Verzeichnet eine Moderationsentscheidung."""
maintenant = datetime.now(timezone.utc)
entry = {
"timestamp": maintenant.isoformat(),
"user_hash": self._pseudonymiser(user_id),
"scores": scores,
"decision": decision,
# Speichern Sie den vollständigen Text standardmäßig NICHT
"texte_longueur": len(text) if text else 0,
"conserver_jusqu_au": (maintenant + timedelta(days=self.retention_jours)).isoformat(),
}
# Speichern Sie Textausschnitt nur, wenn blockiert (für Prüfung)
if decision == "blocked" and text:
entry["texte_tronque"] = text[:200]
return entry
def purger_anciens_logs(self, logs: list[dict]) -> list[dict]:
"""Behält Protokolle bei, deren Aufbewahrungsfrist noch nicht abgelaufen ist."""
maintenant = datetime.now(timezone.utc)
return [
log for log in logs
if datetime.fromisoformat(log["conserver_jusqu_au"]) > maintenant
]
Zwei Vorsichtsmaßnahmen in diesem Code verdienen Erwähnung. Der Pseudonymisierungsschlüssel hat keinen Standardwert: Ein in den Code geschriebener Schlüssel, der allen bekannt ist, würde die Neuberechnung des Hashes für jeden Kennzeichner ermöglichen. Darüber hinaus bleiben pseudonymisierte Daten gemäß der DSGVO (Erwägungsgrund 26) personenbezogene Daten: Dieses Protokoll unterliegt weiterhin Aufbewahrungsfristen und Rechten der betroffenen Personen.
Prüfpfad für die Konformität
Der Prüfpfad beantwortet eine spezifische Frage, die ein Nutzer oder eine Behörde Ihnen stellen könnte: „Warum wurde dieser Inhalt blockiert?” Ohne eine Spur ist Ihre einzige ehrliche Antwort „Ich weiß es nicht mehr” – was angesichts der Tatsache, dass die DSGVO für vollautomatische Entscheidungen gemäß Artikel 22 die Information der Person über die zugrundeliegende Logik verlangt (Artikel 13 bis 15), und der KI-Gesetzgeber eigene Transparenzpflichten hinzufügt, nicht haltbar ist. Der Prüfpfad speichert die Entscheidung, die Bewertungen, die diese motiviert haben, und die Version der angewandten Richtlinie – ohne den Text selbst unbedingt zu speichern.
class AuditTrail:
"""Prüfpfad für Moderationsentscheidungen."""
def __init__(self, storage_path: str):
self.storage_path = storage_path
def record_decision(self, data: dict) -> str:
"""Verzeichnet eine Entscheidung mit einer eindeutigen Kennung."""
import uuid
audit_id = str(uuid.uuid4())
entry = {
"audit_id": audit_id,
"timestamp": datetime.now(timezone.utc).isoformat(),
"type_decision": data.get("decision"),
"modele_moderation": "mistral-moderation-2603",
"scores": data.get("scores"),
"seuils_appliques": data.get("seuils"),
"politique_version": data.get("politique_version"),
"action_prise": data.get("action"),
"base_legale": "interet_legitime",
"responsable": "systeme_automatise"
}
# Schreiben in Audit-Datei
import json
with open(self.storage_path, "a") as f:
f.write(json.dumps(entry, ensure_ascii=False) + "\n")
return audit_id
DSGVO-Checkliste für Ihre KI-Anwendung
Hier sind die Punkte zur Überprüfung, um sicherzustellen, dass Ihr Moderationssystem konform ist:
Rechtliche Grundlage
- Dokumentiertes berechtigtes Interesse an der Inhaltsmoderation
- Benachrichtigung des Nutzers über automatisierte Verarbeitung
- Möglichkeit, eine automatisierte Entscheidung anzufechten
Datenminimierung
- Speichern Sie nur streng notwendige Daten
- Anonymisieren oder pseudonymisieren Sie Benutzerkennzeichner
- Kürzen Sie Texte in Moderationsprotokollen
- Behalten Sie akzeptierte Texte nicht (nur Bewertungen)
Aufbewahrungsfrist
- Definieren Sie eine Aufbewahrungsfrist für jede Datentyp
- Moderationsprotokolle: maximal 90 Tage (es sei denn, eine gesetzliche Verpflichtung verlangt anderes)
- Prüfpfad: gemäß sektoraler Verordnung
- Geplante automatische Bereinigung
Rechte der Nutzer
- Recht auf Zugang zu Moderationsentscheidungen, die sie betreffen
- Recht auf Berichtigung, wenn die Entscheidung angefochten wird
- Recht auf Erklärung der automatisierten Entscheidung
Kernaussagen
- Die DSGVO gilt vollständig für Ihre KI-Moderationssysteme
- Verwenden Sie die Kategorie
piivon Mistral UND Regex, um personenbezogene Daten zu erkennen - Anonymisieren Sie Texte, bevor Sie sie an das Modell senden, wenn möglich
- Pseudonymisieren Sie Benutzerkennzeichner in Protokollen
- Implementieren Sie einen Prüfpfad für die Nachverfolgbarkeit von Entscheidungen
- Definieren Sie eine Aufbewahrungsfrist und bereinigen Sie Protokolle automatisch