Redact before
you prompt.
Redax is a small, deterministic PII engine that strips emails, phones, names, and identifiers from any text — before it reaches an LLM. Built for teams that refuse to send customer data to someone else's GPU.
- Apache-2.0
- No telemetry
- Runs on a laptop
- CPU-friendly
"text": "Hi, I'm Jordan Reyes from Stripe. "
"Reach me at jordan@stripe.com or "
"+1 (415) 555-2671. Card on file: "
"4111 1111 1111 1111."
"text": "Hi, I'm [PERSON_0000] from [ORG_0000]. "
"Reach me at [EMAIL_0000] or "
"[PHONE_E164_0000]. Card on file: "
"[CREDIT_CARD_0000].",
"spans": [ /* 4 spans */ ],
"digest": "8f1d2c…"
Runs on any hardware · CPU-friendly · no telemetry
Privacy as an architecture, not a feature flag.
Most "PII tools" are regex libraries bolted onto an LLM SDK. Redax is a small, deterministic service built for the boring, hard part: making sure the same input always produces the same output, with no leakage and a paper trail.
- 01
Deterministic by design
Same input, same output, every time. Two replicas behind a load balancer return byte-for-byte identical results — no drift, no surprises.
- 02
Privacy is the architecture
No cloud calls. No model phones home. Your text and your telemetry never leave the box you deploy Redax on.
- 03
Drop-in, not rip-and-replace
A single POST endpoint, an OpenAI-compatible shape, and a Python SDK. Wrap any LLM call in five lines.
- 04
Built for production
Idempotency, rate limiting, response cache, Prometheus metrics, OpenTelemetry traces, and an append-only audit log.
Type a sentence. Watch the PII disappear.
This runs the same deterministic regex pipeline that ships in Redax — entirely in your browser. No request is ever made to a server.
One request. Six stages.
No PII survives.
The engine is a small DAG: deterministic regex first, then optional encoders, then consensus fusion. Every stage writes to the audit log; nothing writes the values.
- 01
Regex safety net
Deterministic patterns catch emails, E.164 phones, IBANs, SSNs, IPs, and Luhn-checked credit cards in microseconds.
stage_01 → - 02
GLiNER2 zero-shot NER
A 205M encoder identifies people, organisations, and contextual entities the regex misses. Runs on CPU.
stage_02 → - 03
OpenMed-PII (optional)
A 434M clinical-grade encoder with 54 entity types for healthcare and multilingual workloads. Swap in with one env var.
stage_03 → - 04
Consensus fusion
Spans are merged across detectors, deduped by overlap, and typed with the highest-confidence label.
stage_04 → - 05
Replacement + relex
Deterministic typed placeholders ([EMAIL_0001]) plus optional hiding-in-plain-sight relexicalization.
stage_05 → - 06
Audit log
What was redacted and where — never the value itself. fsync'd, rotated, and signed by default.
stage_06 ●
Everything you'd ship to production. Nothing you wouldn't.
Twelve carefully chosen capabilities. Each exists because a real operator asked for it — not because a competitor had it on a slide.
-
Seven structured PII types
Email, phone (E.164), IBAN, SSN, IPv4, credit card with Luhn check, URL — covered with deterministic regex out of the box.
-
Zero-shot NER on CPU
Default detector is a 0.3B GLiNER2 model that catches PERSON, ORG, and contextual entities without retraining.
-
One env var to swap detectors
Switch to OpenMed-PII for healthcare workloads with `REDAX_DETECTOR=openmed`. No code change.
-
Reversible typed placeholders
`[EMAIL_0001]` instead of `[REDACTED]`. The same entity always maps to the same placeholder across requests.
-
Hiding-in-Plain-Sight relex
Optionally replace names with plausible lookalikes so the output still reads like English.
-
Versioned YAML policies
Field-by-field redaction rules checked into git. Reviewed in PRs, not runtime configs.
-
Append-only audit log
Records what was redacted and where — never the values. Configurable rotation, retention, and fsync.
-
Prometheus + OpenTelemetry
`/metrics` for scraping, OTLP gRPC for traces. SRE-friendly without bolting on a sidecar.
-
Rate limit + idempotency
Per-API-key token bucket in Redis. `Idempotency-Key` short-circuits retries safely.
-
WASM bundle
Same model, INT8-quantised, runs in the browser via Transformers.js. No server round-trip needed.
-
RFC 7807 errors
Every error path returns a problem-details JSON body. Easier debugging, predictable SDKs.
-
Quantified against a benchmark
RedactionBench R-Score measured against `ai4privacy/pii-masking-200k`. Numbers you can defend in review.
One endpoint.
Five lines.
Wrap any LLM call in front of /v1/redact.
PII comes out before the model sees it. Same text in, same text out — every time.
- Endpoint
- POST /v1/redact
- Auth
- X-API-Key header (or auth disabled in dev)
- Idempotency
- Idempotency-Key header short-circuits retries
- Response
- text + spans + digest (sha256 of output)
- Errors
- RFC 7807 problem-details JSON
Numbers we publish.
Numbers you can defend.
Redax is scored against the RedactionBench harness on a 5,060-document stratified sample of `ai4privacy/pii-masking-200k`. The metric rewards both recall and format precision, with a strict penalty for redaction gaps.
Across 5,060 documents
GLiNER2 outperforms OpenMed-PII on both corpora while running 2.1× smaller and 1.4× faster on CPU.
- academic 0.562
- code 0.440
- emails 0.649
- medical 0.581
- financial 0.602
- logs 0.473
Pick the runway that fits the team.
One Docker image. One Python package. One WASM bundle. Every path lands on the same API contract.
- Fastest
Docker Compose
Clones the repo, brings up Redax + Redis, and ships a working stack with one command.
git clone https://github.com/sachncs/redax.git cd redax docker compose up - No clone
Pre-built image
Pull from GHCR and run on any host with a Docker daemon. Useful for CI and air-gapped nodes.
docker run --rm -p 8000:8000 \ ghcr.io/sachncs/redax:latest - Dev-friendly
From source
Install pinned deps from the lockfile and run Redax in a virtualenv. Best for hacking on the engine.
python3 -m venv .venv source .venv/bin/activate pip install -r requirements.lock pip install -e '.[dev]' make dev - Browser
WASM bundle
Same GLiNER2 model, INT8-quantised. Runs locally via Transformers.js with no server round-trip.
import { redact } from '@sachncs/redax/wasm' await redact(text)
Ship privacy the way you'd ship anything else.
Star the repo, run docker compose up,
and you're two curl commands away from a production-grade redaction layer.