Skip to the content.

PrivAiTe

Your coding agent reads your .env files, logs and command output, and everything it reads goes to the LLM provider.

PrivAiTe is a local proxy that sits between your agent or app and the model provider. It replaces the secrets and personal data in every request before it leaves your machine, then puts the personal data back in the reply. It reads inside tool-call arguments and tool results, not only the chat text. Nothing phones home.

See it work Get started See the benchmark GitHub
# your agent reads and sends:
OPENAI_API_KEY=sk-demo-fake000
DB_PASSWORD=demo-pass-4821
ADMIN_EMAIL=marie@example.com
# the provider receives:
OPENAI_API_KEY=[SECRET]
DB_PASSWORD=[SECRET]
ADMIN_EMAIL=<EMAIL_ADDRESS_1>

That is real engine output with the shipped config, not a mock-up. In the reply, <EMAIL_ADDRESS_1> becomes the real address again, streaming included. [SECRET] does not come back: the shipped configs redact secrets and mask card numbers for good (entity overrides). Detection runs locally and is best-effort, not a guarantee: the threat model says what it does not cover.

See it work in one command, no API key

docker run --rm \
  ghcr.io/crp4222/privaite:0.8.0 \
  python -m privaite verify

It starts a throwaway provider on 127.0.0.1, sends the same agent-shaped request straight to it and then through PrivAiTe, and prints which planted values each request body contained. About 20 seconds on a laptop CPU once the image is pulled, and it exits non-zero if a value leaks. What it prints and how to read it.


The problem

People paste real customer names, emails, contracts, and API keys into chatbots and coding agents every day. In this project’s own agent benchmark, a coding agent asked to read a small repository put all 24 planted PII values and secrets on the provider’s wire. Once that text reaches a third-party model, you no longer control where it is stored, logged, or used.

Most existing tools only scrub the visible chat message. Modern traffic is not just chat. It is agents calling tools with your data in the arguments, documents and images attached to a prompt, and CLIs that read files and environment variables where secrets live. That is the gap PrivAiTe was built for.


How it works

  1. You point your OpenAI-compatible client at PrivAiTe instead of the provider.
  2. On the way out, it detects personal data and replaces each item with a stand-in. A placeholder like <PERSON_1>, or a realistic fake, your choice. The mapping stays in memory on your machine for the length of the request.
  3. On the way back, it restores the real values in the response, including inside tool-call arguments, so your application receives what it expected.

The model only ever sees the stand-ins. You can prove it on your own machine in 90 seconds: a runnable demo starts a fake provider that records what it receives, then sends the same agent request without and with PrivAiTe. The engine is open source, so you can also read exactly what it sends.


What other tools miss


Proof, not promises

We built a comparison on real documents, not toy examples. The corpus is 120 real documents whose personal data was labeled independently, then cross-checked. Each solution runs on the same data.

The headline: on the same personal data placed inside a tool-call argument, the text-only guardrails measured (LiteLLM’s built-in Presidio guardrail, LLM Guard) leave 100 percent of it exposed, because they never look there, even for values they detect and scrub in plain text. PrivAiTe removes everything it detects from the tool call; end to end its tool-call leak equals its detection misses (about 15 percent on this corpus), the same misses plain text has. On plain-text recall, the full PrivAiTe preset leads the field.

The benchmark is public and reproducible. Run it yourself.


Ways to run it


Presets


Install

Docker, model baked in, runs offline:

docker run -d -p 8400:8400 \
  -e PRIVAITE_API_KEYS=change-me \
  -e OPENAI_API_KEY=sk-... \
  ghcr.io/crp4222/privaite

Also on Docker Hub as crp4222/privaite.

Or pip:

pip install privaite
python -m spacy download en_core_web_lg

Then point your client at http://localhost:8400/v1 with the key you chose. The full quickstart, config reference, and threat model are in the README.


Docs


What PrivAiTe is not

Honesty is part of the pitch, so here is the fine print in plain words.


FAQ

Does it send my data anywhere? No. Detection runs locally and there is no telemetry. The only outbound request is the one you make to your chosen model provider, carrying stand-ins instead of real values. Outside Docker, a first run also downloads the detection model. Some dependencies contact their vendor by default and PrivAiTe turns each of them off: outbound connections lists them.

Does this make me GDPR or HIPAA compliant? No tool can do that for you. It helps reduce the personal data you expose to a third party, which can support your own compliance work. You remain responsible.

Which models does it work with? Anything with an OpenAI-compatible API, plus local models through Ollama and others.

What about latency? The light preset adds very little. The onnx preset adds more because it runs a model. You choose per use case.

Is it really open source? Yes. Read the engine, run the benchmark, open an issue.