Technischer Leitfaden

PII-sicheres RAG und Agents: Reversible Tokenisierung in Produktion

So hältst du personenbezogene Daten aus LLMs, Vektor-Stores und Logs heraus, ohne das Retrieval zu brechen. Semantische Tokenisierung, Restore-Modi, Sessions und Corpus-gebundenes RAG.

22. Juli 202619 Min. LesezeitOronts Engineering Team

Das Problem: RAG leckt

Ich sag es direkt: In dem Moment, in dem du eine RAG-Pipeline über echte Geschäftsdokumente baust, hast du mit ziemlicher Sicherheit eine Data-Leakage-Maschine gebaut. Kundennamen, IBANs, Gesundheits-IDs und Aktenzeichen fließen aus deinen Dokumenten in drei nicht vertrauenswürdige Orte: den Modell-Provider, den Vektor-Store und deine Logs. Die meisten Teams merken es erst, wenn ein Security-Review oder eine Aufsichtsbehörde fragt, wo die personenbezogenen Daten gelandet sind.

Der naive Fix ist, sie rauszuschneiden. Ersetze jeden Namen durch [REDACTED] und mach weiter. Das bricht zwei Dinge auf einmal. Das Modell verliert den Kontext, den es für gute Antworten braucht, und das Retrieval fällt auseinander, weil die maskierte Query nicht mehr zu den maskierten Dokumenten passt. Du brauchst die personenbezogenen Daten raus aus den nicht vertrauenswürdigen Systemen, aber die Bedeutung muss erhalten bleiben. Das ist das härtere Problem, und es ist lösbar.

Das Ziel ist nicht, personenbezogene Daten aus deiner KI-Pipeline zu löschen. Das Ziel ist, dass die Rohwerte nie in ein System gelangen, dem du nicht vertraust, während das Modell trotzdem genug hat, um seinen Job zu machen.

Wir bauen diese Disziplin in Kundensysteme ein, und wir haben eine Runtime dafür gebaut: OGuardAI, eine proprietäre Datenschutz-Schicht, die zwischen deiner Anwendung und dem Modell sitzt. Dieser Guide ist die Architektur hinter sauber gemachter PII-sicherer KI. Für die Business-Perspektive lies unseren Guide zur KI-Data-Leakage-Prävention, und das ist Kernarbeit unserer KI-Services.

Wen interessiert was

RolleDie eigentliche FrageSo sieht gut aus
KI-EngineerKann ich Daten schützen, ohne das Retrieval zu brechen?Maskierte Query matcht weiterhin maskierte Docs
Security LeadWohin geht rohe PII wirklich?Nie über die Trust Boundary hinaus
DPOKönnen wir Löschung und Rechtsgrundlage nachweisen?Löschung by Design, Entscheidungen geloggt
ArchitektKönnen wir das ergänzen, ohne die App umzuschreiben?Ein Drop-in-Proxy oder ein schlankes SDK
CTOFailt es safe unter Last oder bei Ausfall?Fail closed, nie leaken im Fehlerfall

Die Trust Boundary

Alles beginnt mit einer Linie, die du durch deine Architektur ziehst. Auf der einen Seite die vertrauenswürdige Zone: deine Anwendung und die Protection-Runtime. Auf der anderen die nicht vertrauenswürdige Zone: der Modell-Provider, der Vektor-Store, Third-Party-Tools und deine Logs.

   TRUSTED                          │   UNTRUSTED
                                    │
  App ──▶ Protection runtime ──────▶│──▶ LLM provider
          (detect, tokenize)        │──▶ Vector store
          (restore on the way back) │──▶ Logs, tools
                                    │
  raw PII lives here, transiently   │   only tokens cross this line

Rohe personenbezogene Daten existieren nur transient innerhalb der Runtime, während eines Requests. Was die Boundary überquert, sind Tokens und sichere Metadaten, nie Rohwerte. Das Designprinzip, das das Ganze vertrauenswürdig macht: Konfiguration kann Schutz nur hinzufügen oder verschärfen, nie den eingebauten Floor lockern. Du kannst dir das Leak nicht aus Versehen zurückkonfigurieren. Unser KI-Governance-Guide erklärt, warum diese Haltung, im Zweifel Richtung sicher zu failen, für agentische Systeme so wichtig ist.

Detection: Die sensiblen Stellen finden

Du kannst nicht schützen, was du nicht findest. Die Detection läuft in zwei Schichten.

Die erste ist ein deterministischer Regex-Floor: Dutzende formatbasierte Patterns, die sprachunabhängig sind. E-Mails, Telefonnummern, IBANs, USt-IDs, per Prüfsumme validierte Kreditkarten, IPs, nationale IDs, Steuer-IDs. Die sind schnell, in der Größenordnung von einer Millisekunde, und sie verpassen nie eine wohlgeformte IBAN, weil sie nicht von der Tagesform eines Modells abhängen.

Die zweite ist Named-Entity-Recognition für das, was Regex nicht fangen kann: Personennamen, Organisationen, Orte, Adressen. Das läuft über einen modellbasierten Detektor und ist breit mehrsprachig, zu höheren Latenzkosten.

Der wichtige Teil ist die Failure-Policy. Du wählst einen Modus: nur builtin, both mit sauberem Fallback auf den Regex-Floor, wenn NER down ist, oder advanced, wo NER Pflicht ist und der Request fail closed abbricht, wenn es nicht laufen kann. Ein System, das stillschweigend auf "keine PII-Detection" degradiert, weil ein Sidecar ins Timeout gelaufen ist, ist schlimmer als eines, das den Request verweigert. Fail closed.

ModusVerhaltenNimm ihn, wenn
builtinNur Regex-FloorStrukturierte PII ist das gesamte Risiko
bothRegex plus NER, fällt auf Regex zurückDu willst Namen fangen, kannst aber nicht hart failen
advancedNER Pflicht, failt closed wenn nicht verfügbarNamen und Adressen sind nicht verhandelbar

Semantische Tokens statt Redaction

Hier kommt die Kernidee, die das Modell nützlich hält. Statt eine erkannte Entität zu löschen, ersetzt du sie durch einen strukturierten Token, der ihren Typ und eine eindeutige Identität trägt, aber nicht ihren Wert.

Input:  "Email the invoice to Max Mustermann at max.mustermann@beispiel.de"
Masked: "Email the invoice to {{person:p_001:ad4f97}} at {{email:e_002:5873cc}}"

Der Token sagt dem Modell "hier ist eine Person" und "hier ist eine E-Mail", und er hält sie unterscheidbar und referenzierbar, sodass das Modell eine kohärente Antwort über sie schreiben kann. Der echte Name und die echte Adresse verlassen deine Trust Boundary nie. Auf dem Rückweg stellt die Runtime die echten Werte im finalen Output wieder her.

Das schlägt [REDACTED] in jeder Hinsicht, die zählt. Das Modell behält Struktur und Beziehungen. Identische Werte kollabieren auf denselben Token, das Modell versteht also, dass zwei Erwähnungen dieselbe Person sind. Entitäten, die nah beieinander stehen, lassen sich verknüpfen, sodass ein Name und seine E-Mail kohärent restauriert werden. Redaction wirft all das weg.

Die sechs Restore-Modi

Nicht alles soll vollständig zurückkommen. Die Wiederherstellung wird pro Entität und pro Output-Kanal gesteuert, mit sechs Modi.

ModusWas zurückkommtBeispiel
fullDer komplette OriginalwertDer echte Name
partialEine deterministische TeilmengeNur die letzten vier Ziffern
maskedTypgerechte MaskierungKarte als maskierte Ziffern
formattedWert mit kontextueller FormGeschlechtsbewusste Anrede plus Name
abstractEin semantisches Label, nie der Wert"(E-Mail liegt vor)"
noneKomplett entferntEin Redaction-Platzhalter

So kann eine Support-Antwort an den Kunden seinen Namen voll wiederherstellen, während dieselbe Interaktion im internen Log nur eine maskierte Form bekommt. Der Kanal entscheidet. So lieferst du der Person eine brauchbare Antwort und hältst gleichzeitig deine Logs sauber.

Das RAG-Problem: Retrieval muss weiter funktionieren

Das ist der Teil, an dem jedes Team stolpert, das es selbst bauen will. Wenn du ein Dokument bei der Ingestion mit zufälligen Tokens maskierst und dann die Query des Users zur Suchzeit mit anderen zufälligen Tokens, bricht das Retrieval. Der Query-Token für "Mustermann" matcht nicht den Dokument-Token für "Mustermann", weil beide unabhängig voneinander geprägt wurden.

Der Fix sind deterministische, Corpus-gebundene Tokens. Innerhalb eines Corpus wird ein Wert über einen keyed Hash tokenisiert, sodass derselbe Wert immer denselben Token produziert, in jedem Dokument und in der Query. Jetzt matcht eine maskierte Query maskierte Chunks, weil "Mustermann" auf beiden Seiten identisch tokenisiert wird.

Ingestion:  doc chunk  "...contract with Mustermann..."  ──▶  "...contract with {{person:h_9f3a...}}..."
Query:      "what did Mustermann sign"                    ──▶  "what did {{person:h_9f3a...}} sign"
                                                                       │
                                        same value ──▶ same token ──▶ retrieval matches

Die Tokens werden pro Corpus aus einem Secret abgeleitet, derselbe Wert in einem anderen Corpus ist also ein unverwandter Token, und eine Hash-Kollision failt closed, statt zwei verschiedene Personen zu verschmelzen. Genau das erlaubt dir, Retrieval über maskierte Dokumente mit maskierten Queries zu fahren und trotzdem korrekte Ergebnisse zu bekommen. Die Retrieval-Seite generell behandeln wir in unserem Guide zu Enterprise-RAG-Systemen und im Guide zur Vector-Search-Architektur. Kombiniert mit den Agent-Memory-Patterns aus unserem Agent-Memory-Guide baust du so Agents, die sich erinnern und retrieven, ohne personenbezogene Daten zu horten.

Sessions: Wo das Mapping lebt

Das Mapping von Tokens zurück zu echten Werten muss irgendwo sicher liegen und über Replicas hinweg nutzbar sein. Der Default ist eine versiegelte Session: Das Mapping wird mit AES-256-GCM in einen Blob verschlüsselt, der mit dem Request reist. Der Server hält also keinen State, und jedes Replica kann jeden Request verarbeiten. Für Shared-Setups hält ein verschlüsselter Store nur Ciphertext plus nicht personenbezogene Routing-Metadaten.

Jeder Session-Load re-validiert den Tenant, zu dem sie gehört, und failt closed bei einem Mismatch, sodass ein Tenant nie das Mapping eines anderen entsiegeln kann. Sessions laufen über eine TTL ab, und ein manipulierter oder abgelaufener Blob wird über sein Authentication-Tag abgelehnt. Das ist die langweilige kryptografische Klempnerei, die das Ganze vertrauenswürdig macht, und sie falsch zu machen ist der Weg, auf dem aus "wir tokenisieren PII" ein "wir haben ein Shared-Secret-Leak" wird. Unser Guide zum Designen von Systemen für den Fehlerfall behandelt dieses defensive Mindset.

Policy: Deklarieren, was passiert

Du hartcodest Schutzentscheidungen nicht. Du deklarierst sie in Policy, damit ein Security- oder Compliance-Owner sie lesen und ändern kann, ohne Anwendungscode anzufassen.

name: support-desk
version: 1.0.0
defaults:
  restore_mode: masked
rules:
  - entity_type: credit_card
    action: redact          # nie reversibel, erreicht nie das Modell
  - entity_type: person
    action: tokenize        # reversibel, für den Kunden wiederhergestellt
    restore_mode: full
  - entity_type: email
    action: tokenize
    restore_mode: masked    # maskiert in Logs, voll zum User je nach Kanal

Actions sind explizit: tokenize für reversiblen Schutz, redact für irreversibles Entfernen, abstract für ein grobes Label. Ein unbekannter Policy-Name lässt den Request failen, statt auf etwas Permissives zurückzufallen. Der Floor kann per Policy nicht geschwächt werden, nur verschärft. Das ist Authorization-as-Configuration, und es holt die Security-Entscheidung aus verstreutem Code an einen reviewbaren Ort. Unser KI-Governance-Guide erklärt, warum diese Trennung zählt.

Der Drop-in-Proxy

Der schnellste Weg, eine bestehende App zu schützen, ist, nichts an ihr zu ändern. Ein transparenter Proxy spricht dieselbe API wie dein Modell-Provider. Du zeigst also mit deinem SDK auf die Proxy-URL, und er maskiert auf dem Hinweg und restauriert auf dem Rückweg. Kein Rewrite der Anwendung.

Your app ──▶ proxy (mask) ──▶ OpenAI / Anthropic ──▶ proxy (restore) ──▶ your app

Der Proxy hält die Session, deine App fasst das Token-Mapping also nie an. Für Teams, die engere Kontrolle wollen, geben dir schlanke SDKs in mehreren Sprachen dieselben Primitives mit Framework-Integrationen für die gängigen Agent- und RAG-Stacks. So oder so ist die Integration eine Naht, kein Rewrite, und genau das macht die Adoption praktikabel. Unsere Teams für Individualsoftware und Consulting verdrahten das in bestehende Systeme.

GDPR: Löschung per Revocation

Ein Antrag auf Löschung hat in diesem Modell eine saubere Antwort. Weil das Mapping von Token zu Wert der einzige Link zu den echten Daten in deiner Pipeline ist, widerrufst du es. Das gespeicherte Mapping hält nur keyed Hashes der Werte, nie die Rohwerte, und sobald ein Wert widerrufen ist, restauriert er zu einem Löschmarker, egal was irgendein Session-Blob sagt. Eine replayed oder zurückgerollte Session kann den Widerruf nicht aufheben.

Das gibt dir eine gezielte, nachweisbare Löschung über die gesamte KI-Pipeline, mit Audit-Beleg und ohne rohe personenbezogene Daten im Audit-Trail selbst. Das größere Compliance-Bild behandeln wir in unserem Guide zu GDPR und KI, und wie wir es in der Delivery handhaben, auf unseren Seiten zu Trust und GDPR.

Loslegen

  1. Mappe deine Datenflüsse. Finde jeden Punkt, an dem Dokumente oder Nachrichten das Modell, den Vektor-Store oder Logs erreichen.
  2. Starte mit dem Regex-Floor. Strukturierte PII, IBANs, Karten, E-Mails, ist der schnellste Win mit der höchsten Sicherheit.
  3. Ergänze NER, wo Namen und Adressen zählen. Wähle deinen Failure-Modus bewusst.
  4. Nutze Corpus-gebundene Tokens für RAG. Das hält das Retrieval über maskierte Daten am Laufen.
  5. Deklariere Policy statt Code. Lege die Schutzentscheidungen dahin, wo ein Compliance-Owner sie lesen kann.

Das ist gestaffelte Arbeit mit niedrigem Risiko, und sie passt in die phasenweise Delivery unserer Methodik. Starte über Kontakt oder hol dir ein scoped Angebot.

Wie das typischerweise schiefgeht

  1. Redacten statt tokenisieren. Du verlierst Modellkontext und brichst das Retrieval. Nutze reversible semantische Tokens.
  2. Unabhängige Tokens für Query und Dokumente. Das Retrieval bricht. Nutze deterministische, Corpus-gebundene Tokens.
  3. Stille Degradation bei Detector-Ausfall. "Keine Detection" ist ein Leak. Fail closed.
  4. Schutzlogik verstreut im Code. Niemand kann sie auditieren. Deklariere sie in Policy.
  5. Kein Löschpfad. Wenn du ein Mapping nicht widerrufen kannst, kannst du keinen GDPR-Antrag erfüllen. Designe die Löschung von Anfang an ein.

Wer das baut

Oronts ist eine gründergeführte Softwarefirma in München. Refaat Al Ktifan, unser Gründer und Solution Architect, führt ein Senior-Team über Backend, Security und KI. OGuardAI ist unsere eigene Datenschutz-Runtime, gebaut, weil wir diese Disziplin erst in unserer eigenen KI-Arbeit brauchten, bevor wir sie Kunden empfehlen konnten. Wir mappen deine Datenflüsse, setzen die Schutzschicht als Naht ein und übergeben dir eine Pipeline, die unter GDPR und dem EU AI Act verteidigbar ist. Sieh dir unsere Seiten zu Services und Lösungen an.

Takeaways

  • Eine RAG-Pipeline über echte Dokumente leakt PII per Default an das Modell, den Vektor-Store und deine Logs.
  • Tokenisiere statt zu redacten, damit das Modell Kontext behält und identische Werte verknüpft bleiben.
  • Nutze deterministische, Corpus-gebundene Tokens, damit Retrieval über maskierte Daten weiter funktioniert.
  • Halte das Token-Mapping in verschlüsselten, Tenant-gebundenen Sessions und faile closed bei jedem Fehler.
  • Deklariere Schutz in Policy und erfülle Löschung, indem du das Mapping widerrufst.

"Wir tokenisieren PII" ist leicht gesagt und schwer richtig gemacht. Die Details, Corpus-gebundene Tokens, Fail-closed-Detection, Tenant-gebundene Sessions, trennen eine echte Schutzschicht von einem falschen Sicherheitsgefühl.

Wenn deine KI-Pipeline personenbezogene Daten berührt, erzähl uns, wie sie heute fließen. Starte über Kontakt oder hol dir ein scoped Angebot.

Behandelte Themen

PII-sicheres RAGData-Leakage-Präventionreversible TokenisierungLLM-SicherheitPII-Schwärzungsemantische TokenisierungGDPR KIPrompt-Sicherheitsensible DatenKI-Datenschutz

Bauen Sie gerade so etwas?

Wir entwerfen und betreiben Produktionssysteme wie das in diesem Leitfaden. Sprechen Sie mit den Ingenieuren, die ihn geschrieben haben, ohne Verkaufsgespräch.

Gespräch starten