Local proxy for Claude Code that masks PII and secrets before requests reach the Anthropic API now!
862
privacy-guard-proxy is a local reverse proxy for Claude Code that masks sensitive data before it leaves your machine.
Email addresses, names, IBANs, API keys, IDs, addresses, and other secrets are replaced with placeholders like [EMAIL_1] or [IBAN_1] on the way to the Anthropic API. Detection runs fully in-process. No external redaction service is involved.

Claude Code -> privacy-guard-proxy -> Anthropic API
| masks PII + secrets |
Before a request is forwarded upstream, the proxy scans user messages, tool payloads, and file contents for sensitive data. Matching values are replaced with stable placeholders. Upstream responses are passed through unchanged.
cp config.example.json config.json
go build -o privacy-guard-proxy .
./privacy-guard-proxy
export ANTHROPIC_BASE_URL=http://127.0.0.1:9880
claude
By default:
http://127.0.0.1:9880http://127.0.0.1:9881cp config.example.json config.json
docker compose up -d
The compose setup exposes the same two ports and mounts config.json plus ./logs.
| Content | Masked |
|---|---|
| User messages | Yes |
| File contents returned by tools | Yes |
| Tool inputs such as write/edit payloads | Yes |
| System prompt | No |
| Assistant responses | No |
If api_port is enabled, the browser UI is available at http://localhost:9881.

First login:
adminadminYou are forced to change the password on first login.
The UI lets you:
dry_run mode to log findings without modifying requestsThe built-in API exposes the same detector engine used by the proxy.
# Anonymize text
curl http://localhost:9881/anonymize \
-H "Content-Type: application/json" \
-d '{"text":"Meine IBAN: DE89370400440532013000"}' | jq
# Full scan with findings and placeholder mapping
curl http://localhost:9881/scan \
-H "Content-Type: application/json" \
-d '{"text":"[email protected], +49 171 1234567"}' | jq
# Use selected detectors for this request only
curl http://localhost:9881/scan \
-H "Content-Type: application/json" \
-d '{"text":"...", "detectors":["EMAIL","IBAN","SECRET"]}' | jq
# Health and metrics
curl http://localhost:9881/health
curl http://localhost:9881/metrics
Authentication is optional. If no API keys are configured, requests are accepted without auth.
curl http://localhost:9881/scan \
-H "X-Api-Key: pgk_..." \
-H "Content-Type: application/json" \
-d '{"text":"..."}'
Current limit:
/scan and /anonymize: 120 requests per minuteStart from config.example.json and adjust as needed:
{
"api_port": 9881,
"api_keys": [],
"default_detectors": [],
"default_whitelist": [],
"cors_origins": [],
"ui_password_hash": "",
"proxies": [
{
"type": "claude-code",
"port": 9880,
"upstream": "https://api.anthropic.com",
"privacy_guard": {
"url": "",
"api_key": null,
"detectors": [],
"whitelist": [],
"dry_run": false
}
}
]
}
| Field | Meaning |
|---|---|
api_port | Port for Web UI and REST API. 0 disables both. |
api_keys | Stored API key metadata and hashes for protecting /scan and /anonymize. |
default_detectors | Fallback detector list for API requests that do not specify detectors. Empty means all detectors. |
default_whitelist | Global terms that should never be masked by the REST API. |
cors_origins | Allowed browser origins for the REST API. Empty means CORS is off. |
ui_password_hash | SHA-256 hash of the UI password. Empty means initial admin/admin. |
proxies[].type | Request format. Use claude-code for Claude Code traffic. |
proxies[].port | Local listening port of this proxy instance. |
proxies[].upstream | Upstream Anthropic base URL. |
proxies[].privacy_guard.url | Reserved config field for compatibility. |
proxies[].privacy_guard.api_key | Optional per-proxy upstream API key override. |
proxies[].privacy_guard.detectors | Enabled detector types. Empty means all detectors. |
proxies[].privacy_guard.whitelist | Terms that should never be replaced for this proxy. |
proxies[].privacy_guard.dry_run | Detect and log findings without changing outgoing request bodies. |
For /scan and /anonymize, the runtime whitelist is the combination of default_whitelist and any request-level whitelist.
Legacy configs using a top-level []Config array are still accepted.
| Type | Example | Validation / logic |
|---|---|---|
EMAIL | [email protected] | Regex-based |
PHONE | +49 171 1234567 | DACH-focused, at least 9 digits |
IBAN | DE89 3704 0044 0532 0130 00 | MOD-97 checksum |
CREDIT_CARD | 4111-1111-1111-1111 | Luhn check |
TAX_ID | 86 095 742 719 | German tax ID validation |
SOCIAL_SECURITY | 65 180675 B 003 | German social security format |
KVNR | A123456789 | German health insurance number validation |
VAT_ID | DE 123 456 789 | German VAT ID validation |
PERSONAL_ID | C22990047 | German passport / ID style patterns |
LICENSE_PLATE | M-AB 1234 | German plate formats |
DRIVER_LICENSE | B123456AB | Context-aware driver's license detection |
ADDRESS | Musterstrasse 12, 80331 Muenchen | DACH street + postal code + city |
URL_SECRET | ?token=abc123 | Sensitive query parameter detection |
SECRET | API keys, JWTs, cloud tokens | Large built-in ruleset |
dry_run mode first to see what would be maskedgo build -o privacy-guard-proxy .
go test ./...
Project layout:
internal/
├── api/ # Web UI + REST API
├── detector/ # PII and secret detection engine
└── proxy/ # Reverse proxy and masking pipeline
main.go # Application entry point
config.json # Runtime configuration
Frontend assets are vendored under internal/api/static/vendor/, so the Web UI does not depend on external CDNs at runtime.
Content type
Image
Digest
sha256:780edfe4d…
Size
7.4 MB
Last updated
4 months ago
docker pull noxway/privacy-guard-proxy