Redact PII from LLM prompts, then restore it afterwards. Runs fully local, no egress.
988
Strip PII out of LLM prompts, then put it back afterwards. Runs entirely in the container — no LLM is called and nothing you paste leaves the box.
Paste a prompt, get a redacted version with reversible tokens (<PERSON_1>,
<EMAIL_ADDRESS_1>), send that to any model, then paste the reply back to restore the real
values. There is a web UI, a JSON API, and a desktop tray client that does the same on your
clipboard from any application.
Detection is Microsoft Presidio with spaCy NER models, running in-process.
Source and full docs: https://github.com/Bhairav-Pardiwala/PromptRedactionStudio
docker run --rm -p 8000:8000 bhairavpardiwala/prompt-redaction-studio
Open http://localhost:8000 for the UI, or http://localhost:8000/docs for interactive API
docs. Both spaCy models (en_core_web_sm and en_core_web_lg) are baked in, so nothing is
downloaded at startup and the container needs no network access at all.
curl -X POST http://localhost:8000/api/redact \
-H "Content-Type: application/json" \
-d '{"text":"Email Dana Whitfield at [email protected] or call +1 415 555 0132.",
"engine":"spacy_lg","default_operator":{"type":"placeholder","params":{}}}'
{
"session_id": "wItW2Byi5zAf9FpVbVLAsw",
"redacted_text": "Email <PERSON_1> at <EMAIL_ADDRESS_1> or call <PHONE_NUMBER_1>.",
"mapping": {
"<PERSON_1>": "Dana Whitfield",
"<EMAIL_ADDRESS_1>": "[email protected]",
"<PHONE_NUMBER_1>": "+1 415 555 0132"
},
"reversible": true,
"engine": "spacy_lg"
}
POST /api/restore with the model's reply and that session_id puts the real values back —
it locates each token wherever the model happened to put it, and reports any it never
repeated rather than silently dropping them.
Routes: /api/analyze, /api/redact, /api/restore, /api/config, /api/policy,
/api/health.
"store_session": false
and the server keeps nothing at all — the desktop client always does, and restores locally.HEALTHCHECK on /api/health.| Env var | Effect |
|---|---|
REDACTION_API_KEY | When set, /api/analyze, /api/redact and /api/restore require an X-Redaction-Key header (constant-time compared). Unset = no auth, for trusted networks. |
REDACTION_POLICY_FILE | Path to a YAML file of org-wide defaults served by /api/policy. Unknown keys are ignored rather than passed through, so a typo cannot silently change redaction behaviour. |
Port 8000 is exposed. Override the command to change it:
docker run -p 9000:9000 bhairavpardiwala/prompt-redaction-studio \
uvicorn app.main:app --host 0.0.0.0 --port 9000
latest and semver tags such as 1.0.0. Built for linux/amd64 and linux/arm64 on
native runners, so it runs natively on Intel and Apple Silicon. The pull is roughly 550 MB.
Building from source, --build-arg INCLUDE_LARGE_MODEL=false produces a much smaller image
with only en_core_web_sm, which detects noticeably fewer names and places.
Built in GitHub Actions with a build attestation:
gh attestation verify --owner Bhairav-Pardiwala \
oci://bhairavpardiwala/prompt-redaction-studio:1.0.0
A pass means the image came from that repository's CI and has not been altered since. It is not a statement that the code is free of bugs.
All names, cards and IDs in the sample prompt, tests and screenshots are synthetic — no real personal data is in this image or the repository.
This was built quickly with an AI assistant rather than hand-reviewed line by line. The test suite covers the behaviour that matters, but it has not been audited the way a tool handling real personal data deserves. Run it locally or on infrastructure you own and have hardened yourself — there is deliberately no hosted demo.
MIT licensed.
Content type
Image
Digest
sha256:aea6657ff…
Size
543.9 MB
Last updated
27 days ago
docker pull bhairavpardiwala/prompt-redaction-studio