PII redaction

Every AI coding agent, chat window and MCP tool ships context outward: file contents, stack traces, tickets, logs. That context routinely contains secrets (API keys, tokens) and personal data (names, emails, PESEL numbers, addresses). PII redaction for LLMs is the pattern of detecting and masking that data at an interception point before it leaves your boundary — the same zero-trust idea as an egress firewall, applied to prompts.

The space splits cleanly along two axes: where you intercept, and how you detect.

Where you intercept

  • Client hooks — the agent harness itself runs your redaction code on every tool call. claude-code-redaction-hooks (OSS) wires PreToolUse/PostToolUse stages into Claude Code’s settings.json; ruvnet’s gist shows the same shape as a drop-in config. Zero added latency, no infrastructure — but bound to one harness.
  • Local LLM proxies — point the agent at a local OpenAI/Anthropic-compatible endpoint that sanitizes before forwarding upstream. pasteguard (OSS) masks PII or routes the request to a local LLM entirely; DontFeedTheAI (OSS) does it for pentest engagements with a per-engagement vault and reversible mapping. The LiteLLM + GLiNER-PII guardrail recipe is the same pattern assembled from parts: ANTHROPIC_BASE_URL=http://localhost:4000, prompts auto-sanitized in <100 ms (litellm (OSS), GLiNER2 (OSS)).
  • MCP tool proxies — the newest interception point, between agent and tools rather than agent and LLM. gs-mcp-proxy-pii-redactor (OSS) redacts PII from Jira/GCP-log MCP responses so agents can work tickets without ever seeing real identifiers.
  • Browser extensions — proxy the human instead of the API. presidio-local-anonymizer (OSS) anonymizes text typed into ChatGPT/Claude/Perplexity web chats, offline, covering the surface no API proxy can intercept.
  • Commercial self-hosted — Sheathe (self-hosted masking layer for Claude Code, regex + on-prem LLM classifier, ~90 ms added, $400 solo lifetime) and Liquid AI’s ShieldFlow (request-access, no public details yet).

How you detect

  • Regex + NER pipelines — the incumbent. presidio (OSS) (Microsoft, transferred to the data-privacy-stack org, 11k★) is the reference architecture: analyzer + anonymizer split, spaCy/stanza NER plus pattern recognizers, customizable pipelines.
  • Dictionary matching at scale — GrowthSpace’s proxy matches a ~100k-entry customer dictionary via an Aho-Corasick automaton in linear time, on top of a pattern scanner for emails/phones.
  • Transformer NER, schema-as-prompt — entity types described in text and embedded in the same vector space as the input, so the model generalizes zero-shot to new types and odd formats. GLiNER2 (OSS) industrializes this; pii-masker (OSS) fine-tunes DeBERTa-v3 for it; AnonimiNER applies it to Polish; desert-ant-labs/redact shrinks it to an 11.6 MB on-device token classifier covering 27 languages.
  • Dual-layer hybrid — DontFeedTheAI (OSS) runs a local Ollama LLM for context-aware detection with a regex safety net underneath; cheap determinism catches what the model misses.

The Polish problem

Presidio’s weakness on Polish text is the concrete benchmark in this cluster: spaCy’s Polish model is far weaker than its English one, and its regexes assume rigid formats. AnonimiNER (@AlexObuchowski’s announcement, captured with the benchmark chart below) reports recall on Polish data:

EntityAnonimiNERPresidio
PESEL numbers100%25.81%
Phone numbers100%20.31%
Home addresses87.70%47.54%

The schema-as-prompt architecture is why: a bidirectional encoder pre-trained on Polish handles inflection (Kowalski/Kowalskiego/Kowalskiemu as one entity) and understands from context that PESEL: marks PII even when the digits don’t match the canonical format. Relevant any time Polish personal data meets an LLM — GDPR/RODO makes it a compliance requirement, not a nicety.

Resources

Captured 2026-09-24 via the capture ETL (clippings are private, referenced by path):