返回博客
Compliance·2026年5月25日·8 min read

DSGVO-konformer LLM-Einsatz — PII-Maskierung, AVV und Zero Data Retention

Praktischer Leitfaden für deutsche Unternehmen, die Claude / Gemini / GPT DSGVO-konform in Produktion einsetzen wollen. Code für PII-Maskierung, AVV-Mustertexte, Anthropic / Google Zero Data Retention für Enterprise, Audit-Logs mit Request-ID-Korrelation und die Schrems-II-Frage.

DSGVO-konformer LLM-Einsatz in deutschen Unternehmen — was du brauchst, bevor Claude oder GPT in Produktion gehen darf. Praktisches Setup mit PII-Maskierung, Audit-Logs, Zero Data Retention bei Anthropic / Google, und der AVV-Frage.

Die drei Pflicht-Bausteine

  1. PII-Maskierung vor dem Upstream-Aufruf — Du darfst Klartext-Personendaten nicht ungefiltert an US-Anbieter senden
  2. Auftragsverarbeitungsvertrag (AVV / Art. 28 DSGVO) — mit Kunavo und den Upstreams (Anthropic, Google, OpenAI)
  3. Audit-Trail — Jeder Aufruf nachvollziehbar, mit Zweckbindung dokumentiert

1) PII-Maskierung — der praktische Teil

Bevor ein Prompt das eigene Backend verlässt, läuft er durch einen Maskierungsschritt. E-Mails, Telefonnummern, Personennamen, IBANs, Sozialversicherungsnummern werden durch Tokens ersetzt:

pii_mask.py
# Vor jedem LLM-Aufruf PII maskieren — niemals Klartext-Personendaten
# an die Upstream-API senden.
import re
from openai import OpenAI

PII_PATTERNS = [
    (re.compile(r"[\w.+-]+@[\w-]+\.[\w.-]+"), "<EMAIL>"),
    (re.compile(r"\b\d{4,}\b"), "<NUMBER>"),
    (re.compile(r"\b(?:\+49|0)\s*\d{2,4}\s*\d{4,8}\b"), "<PHONE_DE>"),
]

def redact(text: str) -> tuple[str, dict[str, str]]:
    redacted = text
    mapping: dict[str, str] = {}
    for i, (pat, tag) in enumerate(PII_PATTERNS):
        for match in pat.finditer(text):
            key = f"{tag}_{i}_{match.start()}"
            mapping[key] = match.group(0)
            redacted = redacted.replace(match.group(0), f"[{key}]")
    return redacted, mapping

def restore(text: str, mapping: dict[str, str]) -> str:
    for key, original in mapping.items():
        text = text.replace(f"[{key}]", original)
    return text

Die Mapping-Tabelle bleibt nur lokal. Wenn die LLM-Antwort wieder eingefügte Personendaten zurückgeben muss (z. B. „Hallo Frau Schmidt"), machen wir die Substitution erst nach der Antwort. So sieht der Upstream immer nur anonymisierten Text.

2) AVV — wer braucht welchen Vertrag

  • Du ↔ Kunavo: AVV nach Art. 28 DSGVO. Verfügbar auf Anfrage über sales@kunavo.com — wir schicken den Mustertext binnen eines Werktages
  • Kunavo ↔ Upstream-Anbieter: wir haben AVVs mit Anthropic, OpenAI und Google. Du erbst diese als Sub-Verarbeiter-Klausel in unserem AVV mit dir
  • Schrems-II-Risiko: Anthropic und OpenAI sitzen in den USA. Die Standardvertragsklauseln (SCC) sind in unserem AVV abgebildet. Wenn dein Risiko-Assessment einen reinen EU-Anbieter verlangt, sprich uns auf Mistral als Upstream an (in der Roadmap)

3) Audit-Log — jeden Call protokollieren

Pro Anfrage: Request-ID, User-ID, Modell, gehashter Prompt, Token-Verbrauch, Latenz, X-Request-ID-Korrelation zur Kunavo-Seite:

audit.py
# Jeder LLM-Aufruf wird in einem unveränderlichen Audit-Log festgehalten
import json, time, uuid
from datetime import datetime

def call_with_audit(user_id: str, prompt: str, model: str) -> dict:
    request_id = str(uuid.uuid4())
    redacted_prompt, mapping = redact(prompt)

    # Audit-Log VOR dem Call schreiben
    audit_log.write({
        "request_id": request_id,
        "user_id": user_id,
        "timestamp": datetime.utcnow().isoformat(),
        "model": model,
        "prompt_redacted": redacted_prompt,
        "prompt_hash": hashlib.sha256(prompt.encode()).hexdigest(),
        "pii_tags_count": len(mapping),
    })

    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": redacted_prompt}],
        extra_headers={
            "X-Request-ID": request_id,  # für Kunavo-seitige Korrelation
        },
    )

    response_text = resp.choices[0].message.content
    # Bei Bedarf PII zurück mergen (nur in der lokalen DB)
    final_text = restore(response_text, mapping)

    audit_log.write({
        "request_id": request_id,
        "response_redacted": response_text,
        "tokens": resp.usage.model_dump(),
        "duration_ms": int((time.time() - start) * 1000),
    })
    return {"text": final_text, "request_id": request_id}

Mit der X-Request-ID kannst du in deinem AVV-Vorgang gegenüber dem Kunden nachvollziehen, welcher Upstream den Call bedient hat und welche Tokens dort gerechnet wurden. Kunavo stellt dieselbe Request-ID in unserem Usage-Dashboard dar.

Zero Data Retention (ZDR) bei Upstreams aktivieren

Standardmäßig speichern Anthropic und Google Logs der Prompts für 30 Tage (Anthropic) bzw. 60 Tage (Google) für Abuse-Monitoring. Für DSGVO-sensible Workloads kannst du ZDR anfordern:

  • Anthropic ZDR: über Kunavo für Enterprise-Verträge ab $3.000/Monat aktivierbar. Schreibe an sales@kunavo.com mit der Liste der Modelle, für die ZDR gelten soll
  • Google Vertex AI: Ähnliche Bedingungen, plus die Möglichkeit, EU-Region zu wählen (europe-west4 / Niederlande)
  • OpenAI: Zero Data Retention nur für Enterprise-Tier. Auch hier über uns vermittelbar

Datenresidenz

  • Kunavo-Routing: stateless am Edge in mehreren Regionen
  • Persistenz von Account-Daten: primäre Region mit Multi-Region-Replikation. Auf Enterprise-Anfrage EU-only-Routing möglich
  • Stripe-Tax: USt wird automatisch korrekt für jede EU-Region berechnet und auf der PDF-Rechnung ausgewiesen

Was die meisten Compliance-Teams übersehen

  • Prompt-Inhalt ist personenbezogen, wenn er Namen enthält — auch wenn der User nicht "Müller" eingegeben hat, sondern nur "ich heiße Petra". Maskierung sollte heuristisch erste Namen + Eigennamen erfassen
  • Training auf deinen Daten ist bei Anthropic und Google per default ausgeschaltet (im Gegensatz zu ChatGPT-Konsumenten). Mit ZDR haben wir das vertraglich abgesichert
  • Output-Inhalte hashen — wir speichern bei dir nur den Hash, nicht den vollständigen Text, falls dein DPA das vorgibt
  • Recht auf Löschung — bei einer DSGVO-Anfrage Art. 17 musst du den Prompt aus deinen Logs löschen können. Das funktioniert nur, wenn deine Audit-Logs deletable sind (also nicht in append-only-Blockchain-Strukturen)

Impressum & Cookie-Banner

Für eine vollständige Compliance-Strecke siehe unser /legal/impressum nach § 5 TMG sowie die Datenschutzerklärung unter /legal/privacy. Cookie-Banner pflegst du auf deiner eigenen Website (z. B. mit Usercentrics, Cookiebot oder Klaro) — Kunavo selbst setzt nur funktionale Cookies.

Bereit? Kostenlose Registrierung mit $2 Startguthaben. AVV-Anfrage direkt an sales@kunavo.com.