Antonio Maiolo

noirdoc - PII guard for Claude Code to keep client data out of context

by
Open-source plugin that redacts PII before Claude Code reads it. Names, emails, and IBANs become placeholders Claude sees; you reveal originals locally. Same engine ships as a CLI for any LLM and a hosted proxy for OpenAI/Anthropic/Azure.

Add a comment

Replies

Best
Antonio Maiolo
Hey — I built noirdoc because I kept seeing the same pattern on consulting engagements: a team wants to use Claude on a real customer ticket, and Legal kills it because the prompt would leak names, IBANs, and addresses to a third party. The plugin is a PreToolUse hook for Claude Code. When Claude tries to read a file from a path you mark sensitive, the plugin redacts it first — names become `<>`, IBANs become `<>` — Claude works on the placeholders, and you reveal the originals locally in your own terminal. Real names never enter Claude's transcript. Detection runs locally — Presidio + Flair + GLiNER ensemble, German-tuned (it handles "Müller, Anna" and lowercase legal text where most tools fail). Reversible, with consistent placeholders across sessions. Same engine ships three ways: this plugin (OSS), a CLI on PyPI for any LLM workflow (OSS), and a hosted proxy that does the same thing transparently for OpenAI / Anthropic / Azure calls if your team needs that. Curious what you'd want it to redact next — what's the data you can't paste into an LLM today?
Anusuya Bhuyan
Privacy isn’t optional anymore. This gets it
Alex Isa

voice→form widgets are the case i kept hitting — transcribed names, addresses, phone numbers flowing straight into prompts before anyone notices. the moment you try to use real customer voice samples, Legal blocks the whole pipeline.                 

the German-tuned detection is the part that actually matters — most tools fail on lowercase legal text and "Müller, Anna" patterns, and false positives there kill adoption faster than missed PII.

Zabbar

apart from finance information is it able to detect some credentials been passed accidentaly?

Antonio Maiolo

@zabbar Not yet, but we have it on the roadmap!

Elijah Bowlby

This solves a real pain point. I work at a fintech and we hit the same wall constantly: engineers want to use Claude Code on production support tickets but the moment there's a customer IBAN or address in the file, compliance shuts it down. The PreToolUse hook approach is smart because it catches things before they ever leave your machine. Curious about the performance overhead on large files (e.g. 10K+ line logs with scattered PII). Does the Presidio+Flair ensemble add noticeable latency, or is it fast enough to feel invisible during normal Claude Code usage?

Antonio Maiolo

@elijahbowlby Honest answer: it will not be invisible on 10K-line files with the full pipeline. Flair's the bottleneck here. For huge logs you can drop Flair and run Presidio + spaCy only — ~10× faster, you lose some German name recall but the regex layer still catches IBANs and emails (which is the actual fintech failure mode).

The hook is async, so Claude Code shows a "redacting…" state instead of blocking. But yeah — for large files, you will feel the latency!

Robert Douglass

How do you detect names? A dictionary? An LLM or model of some sort?

Antonio Maiolo

@robert_douglass No a dictionary would be too brittle, it uses a combination of tools.


Presidio handles regex-based PII (IBAN, email, tax IDs). For names, we use three NER models, all local:

  • The NER component of spaCy's de_core_news_lg pipeline (called via Presidio)

  • Flair's de-ner-large (dedicated NER model, separate pass — catches "Schmidt, Lisa" comma-form and lowercase legal text)

  • GLiNER (zero-shot — add custom entity types at runtime without retraining)

Each NER fails differently, so the three vote together, because the union has better recall than any single one.