Skip to content

Latest commit

 

History

69 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cordon

ci codeql OpenSSF Scorecard license

A PII-redacting proxy for the OpenAI and Anthropic APIs. Point your client at cordon instead of the provider. Emails, phone numbers, card numbers, SSNs, API keys and the rest are replaced with placeholders before the request leaves your network, and put back in the reply so your app never notices. One container, no database, no ML model, no client code changes beyond the base URL.

your app ──▶ cordon ──▶ api.openai.com / api.anthropic.com
              │
              ├─ model receives:    email <EMAIL_5285D1_1> re card <CREDIT_CARD_5285D1_1>
              └─ your app receives: email john@acme.com re card 4012-8888-8888-1881

Quickstart

docker run -d --name cordon --init -p 127.0.0.1:8080:8080 \
  -v cordon-data:/app/data -e ADMIN_TOKEN=change-me \
  ghcr.io/askalf/cordon:v0.3.0

Then change one thing in your client: the base URL. Anthropic clients use http://localhost:8080, OpenAI clients use http://localhost:8080/v1. Your provider key goes through untouched; cordon never holds it. Every response says what it did: X-Redacted: 2, X-Redacted-Types: EMAIL:1,CREDIT_CARD:1.

A full captured round trip (both clients, the headers, what the provider was sent and the audit line) is in docs/reference.md.

What it catches

Deterministic detection: regex plus checksum validators, no ML dependencies, fully auditable. Every entity with a check digit is validated before its span is accepted (Luhn for cards, ISO 7064 mod-97 for IBANs, ABA for routing numbers, SSN area/group rules), and overlapping matches resolve by precedence so a 16-digit card is not also clipped as a phone number.

set entities
pii EMAIL, PHONE, SSN, IPV4, IPV6, MAC, STREET_ADDRESS
phi MRN, DATE (and SSN)
pci CREDIT_CARD, IBAN, US_ROUTING
secrets OpenAI / Anthropic / AWS / GitHub / Google / Slack keys, JWTs, Bearer tokens, PEM private keys

All four sets are on by default; narrow per tenant or per request with X-Redact-Sets: pii,pci.

How it behaves

  • Fails closed. If detection throws, the request is blocked, never forwarded with PII intact (FAIL_MODE=closed, the default). The test suite asserts the upstream is never called on that path.
  • Three modes, per tenant or per request (X-Redact-Mode):
    • reversible (default): placeholders go up, real values come back in the reply, including mid-stream. Tokens carry a per-request random nonce (<EMAIL_5285D1_1>, not <EMAIL_1>) so a caller's own placeholder-shaped text can never be rewritten to a real value.
    • strip: irreversible placeholders ([EMAIL]); nothing is restored. For when the answer never needs the real value.
    • off: passthrough, still audited as a bypass.
  • Tamper-evident audit. Every request appends a hash-chained record of counts and types, never values; npm run audit verifies the chain.
  • Per-tenant policy: consistent pseudonyms, data residency (regional upstreams), durable policy store.
  • Signed releases: multi-arch GHCR images with keyless Sigstore provenance and an SBOM.
X-Redact-Mode: strip   →   "text":"email [EMAIL] re card [CREDIT_CARD]"

What it does not do

  • Names, free-text addresses, medical conditions. There is no NER. A person's name in prose passes through. The detector is an interface (src/detect), so a Presidio-style sidecar can be added; it is not included.
  • Embeddings, count_tokens, images. Only the three generation endpoints (/v1/chat/completions, /v1/responses, /v1/messages) are redacted; other /v1/* paths, including /v1/responses/{id}, pass through verbatim. Image and file parts are left untouched.
  • Token counts. Streaming usage figures are the provider's, computed on the de-identified text.

If you need one of those, say so in an issue. The scope above is deliberate, not accidental.

Reference

Part of Own Your Stack

cordon guards the prompt. The rest of the Own Your Stack tools guard the agent around it: redstamp contains the tool call, truecopy vets the tool before it is installed, browser-bridge governs the browser, and plumbline watches the whole action sequence against the declared job. cordon and plumbline sit beside that path rather than in it.

About

Own your prompts: a PII-redacting LLM gateway that fails closed, so personal data never leaves your perimeter.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages