PII goes in tokenised, comes out real.
Reversible redaction tokenises personal data before the LLM sees it and substitutes the real values back into the response. The model gets [[EMAIL_001]], your user gets their actual address — best of both worlds without the privacy cost.
Static masking ruins the response.
If you replace jane@example.com with [REDACTED] on the way in, the LLM has no anchor for what it's reasoning about. It can no longer reference the email, can't generate a polite reply that addresses the person, can't compose a follow-up. The user gets generic boilerplate where they expected something useful.
Worse: the LLM might still hallucinate a plausible email back into the response — and now you've leaked a fake address as if it were real.
Reversible redaction fixes both: the model sees a stable placeholder it can reason about, and the gateway substitutes the real value back into the output. PII never reaches the provider, your user gets a coherent answer.
— Request from your app — { messages: [{ role: "user", content: "Reply to jane@acme.com about IBAN DE89..." }] } — What the LLM actually sees — { messages: [{ role: "user", content: "Reply to [[EMAIL_001]] about IBAN [[IBAN_002]]" }] } — LLM response — "Hi [[EMAIL_001]], the transfer to [[IBAN_002]] is confirmed." — What your user receives — "Hi jane@acme.com, the transfer to DE89... is confirmed."
# Per-project policy — applied to every request through the gateway detectors: email: on phone: on iban: on ssn: on ip_v4: on ip_v6: on custom: - name: employee_id regex: 'EMP-\d{6}' label: "EMPLOYEE_ID" - name: internal_url regex: 'https?://internal\.acme\.com/\S+' label: "INTERNAL_URL" # Reversible map is request-scoped — every detection generates # a stable [[LABEL_NNN]] token that maps back to the original. # Map lives only in the request lifecycle, never persisted.
Detect, tokenise, substitute.
- Detect — a configurable set of regex + contextual matchers scans the request body before it leaves the gateway.
- Tokenise — every match is replaced with a stable
[[LABEL_NNN]]placeholder. A request-scoped map remembers the mapping. - Substitute — when the LLM responds, the same placeholders in the output get swapped back to their original values before the response leaves the gateway.
The detection policy is per-project. Built-in detectors cover the common categories; custom regex slots add anything else (employee IDs, internal URLs, internal usernames, …). Detection events go into the audit log so you can see what was redacted, when, by which token.
Detector catalogue, opt-in per project.
Defaults are conservative — the high-confidence detectors are on; the rest opt-in.
- Email addresses — RFC 5322 grammar
- Phone numbers — international + local formats
- IBANs — checksum-validated
- Credit cards — Luhn-validated
- US SSNs — area-block ranges
- EU social-IDs — DE, FR, ES, IT, NL
- IPv4 / IPv6 — public address ranges only
- Names — contextual ML detection (opt-in)
- Postal addresses — multi-line, country-aware
- Custom regex — any pattern, any label
PII protection without the UX tax.
Built into every project type — turn it on per project, customise the detector set, and the response your users see still contains the real values.