Skip to content
HN On Hacker News ↗

GitHub - crp4222/PrivAiTe: Self-hosted PII redaction proxy for LLM APIs and agent CLIs. Scrubs names, emails and secrets from Claude Code, Codex and any OpenAI-compatible app before requests leave your machine, tool-call arguments included, then restores them in the reply. Local detection, zero telemetry.

▲ 9 points by crp4222 2w ago HN discussion ↗

Pangram verdict · v3.3

We believe this text is mainly AI, with some human-written content.

95 %

AI likelihood · overall

AI
3% human-written 97% AI-generated
SEGMENTS · HUMAN 0 of 4
SEGMENTS · AI 2 of 4
WORD COUNT 460
PEAK AI % 88% · §3
Analyzed
Aug 13
backend: pangram/v3.3
Segments scanned
4 windows
avg 115 words each
Distribution
3 / 97%
human / AI fraction
Verdict
AI
Pangram v3.3

Article text · 460 words · 4 segments analyzed

Human AI-generated
§1 AI · 88%

Self-hosted PII redaction proxy for LLM APIs. A drop-in LLM proxy that replaces PII before it reaches the provider, including inside tool-call arguments and multimodal content, with zero telemetry. Told in writing to report its config variables but never their values, Claude Code sent 3 of 4 secrets to its provider anyway: the same secrets also sat in a log file the task had it read. Over that session 23 of 24 planted values reached the provider; through PrivAiTe's agent gateway, 2 of 24. Wire-level captures of real agent sessions, and the two that still get through are documented rather than rounded away: the measurement, what it misses. You type: "Je m'appelle Marie Dupont, email marie@acme.com" LLM sees: "Je m'appelle <PERSON_1>, email <EMAIL_ADDRESS_1>" LLM says: "Bonjour <PERSON_1>, votre email <EMAIL_ADDRESS_1> est noté." You see: "Bonjour Marie Dupont, votre email marie@acme.com est noté." PrivAiTe sits between your app and the model provider. It finds names, emails, phones, cards, IBANs, secrets and more, swaps them for stand-ins before anything leaves your machine, and puts the real values back in the reply. Two types are deliberately not put back: both shipped configs mask CREDIT_CARD and redact SECRET (entity overrides), which throws the original away on purpose. Most tools scan only the plain message text; agent traffic hides PII inside tool-call JSON, and that is the gap PrivAiTe closes. Detection runs locally (two engines, Presidio + OpenAI's open privacy-filter model), and the engine runs three ways: standalone proxy, Open WebUI filter, or LiteLLM guardrail. This is local pseudonymization, not anonymization, and detection is best-effort rather than a guarantee. You remain the data controller. The Threat model spells out exactly what it protects against and what it does not. Quick start Docker (fastest): the detection model is baked in, so it runs offline from the first request.

§2 Mixed · 36%

docker run -d -p 8400:8400 \ -e PRIVAITE_API_KEYS=change-me \ -e OPENAI_API_KEY=sk-...

§3 AI · 88%

\ ghcr.io/crp4222/privaite The same image is on Docker Hub too: swap the last line for crp4222/privaite if you prefer pulling from there. Two keys, two roles: PRIVAITE_API_KEYS is the key your client sends to PrivAiTe (pick any value); OPENAI_API_KEY is your real provider key, which stays in the container and never reaches your client. This exposes gpt-4o-mini and gpt-4o; for any other provider (Ollama, Azure, anything LiteLLM supports), mount a config: configuration. pip: pip install privaite # One spaCy model per scanned language; the default preset scans EN + FR.

§4 Mixed · 54%

python -m spacy download en_core_web_lg && python -m spacy download fr_core_news_md cat > privaite.yaml <<'EOF' providers: - model_name: gpt-4o-mini litellm_params: model: openai/gpt-4o-mini api_key: ${OPENAI_API_KEY} pii: enabled: true preset: onnx # or "light": faster, no model download, classic PII only EOF # Your real provider key: the config above interpolates it, and startup fails if it is unset.