The Semantic Firewall is a local gateway that sits between your coding agent and the model API. On the way out it swaps your customer names, codenames, hostnames and secrets for realistic, deterministic surrogates. On the way back it reverses them, before your machine ever runs a command. The model reasons in a pseudonymous universe; your team works in the real one. The mapping key never leaves the building.
The contract says zero retention. Legal still says no.
Frontier models are now good enough to live inside your codebase. The blocker is rarely capability — it is the gap between what a vendor promises and what your security team is willing to bet the crown jewels on.
01 / Problem
The promise is policy, not physics
Zero-retention and no-training clauses are real and worth having. But they are commitments enforced by audits and trust, not by the laws of arithmetic. A subpoena, a misconfiguration, or a breach at the other end is outside your control the moment the bytes leave.
02 / Problem
Coding agents leak the most
A coding agent does not just see your prompt. It reads files, runs commands, and streams every Bash result and stack trace back into the next request. Your real hostnames, table names, customer IDs and the occasional pasted secret ride along — far more than anyone reviews.
03 / Problem
So the best tools stay banned
The rational response is a blanket ban: no agents on the monorepo, no model near the customer data. The capability is right there, and the organisation cannot use it. That is the cost of an all-or-nothing trust decision.
The insight
Names are ciphertext. Structure is the plaintext.
Most enterprise secrets are referential, not structural. The model does not need to know that the customer is Northwind Trading or that the box is prod-db-07. It needs the grammar, the types, the control flow and the logic. Those it gets in full.
What Claude Code sees locallyREAL
// incident: customer can’t auth
curl https://api.northwind-trading.com/v1 \
-H "x-api-key: sk-live-9f3c2a8e41bd" \
--resolve prod-db-07:5432
// → 401 from billing-svc for acct 80431
BillingError: tenant 80431 over quota
What Anthropic’s servers seeSURROGATE
// incident: customer can’t auth
curl https://api.brightmere-supply.com/v1 \
-H "x-api-key: SF_SECRET_apikey_4b1e7c" \
--resolve host-a2f19c:5432
// → 401 from ledger-svc for acct 51277
BillingError: tenant 51277 over quota
The bug is identical in both columns. The 401, the quota logic, the shape of the request, the relationship between the customer and the failing service — all preserved. Only the swappable names changed. This is PCI-style tokenisation, lifted from card numbers to the semantic layer.
How it works
One gateway on localhost. Everything flows through it.
Claude Code and every Anthropic SDK honour ANTHROPIC_BASE_URL. Point it at the gateway and you are done — no patches to the agent, no change to how your engineers work. The gateway transforms requests on the way out and reverses responses on the way in.
Request · real → surrogateResponse · surrogate → real
Step 01
Detect
A typed dictionary from your config plus secret and PII patterns — AWS keys, GitHub tokens, sk-keys, JWTs, private keys, emails, IPs — find the sensitive nouns in the system prompt, files and every tool result.
Step 02
Surrogate
Each entity is keyed through HMAC into a realistic, type-matched stand-in: a plausible company, a documentation-range host, a same-shape ID. Secrets become an obviously-redacted placeholder. Same input, same output, always.
Step 03
Egress guard
After transforming, the outgoing payload is re-scanned. If any secret or PII class survived, the request is blocked, logged, and held until an explicit override. The default is fail-closed — never fail-open.
Step 04
Reverse
On the response — streaming or not — surrogates are mapped back to real values in text, tool inputs and thinking, before your agent acts. A command Claude returns runs against your real host, not the fake one.
Step 05
Ledger
Every exchange appends a hash-chained audit record: what categories were redacted and how many, never the values. A verify command proves the chain has not been tampered with.
See it on the wire
Not a mock-up. A real capture.
This is a verbatim round-trip from the build’s integration tests. The left column is exactly what left the machine for Anthropic’s servers — every accented token is a surrogate. The right is what the developer saw after the gateway reversed the response. Same bytes, swapped names.
Customer: Initech. Primary DB host: db-prod-01.initech.internal. Internal API: https://api.initech.internal/v2 at 10.4.12.9. Service: billing-core. Module: InitechBilling. Reporting table: revenue_q3_actuals. Project codename: Project Bluefin. Owner: Dana Whitfield <dana.whitfield@initech.example>.
Captured worst-case: the response was streamed one character per delta and the client still restored all ten entities byte-identically. The mapping never appeared in either payload — only on this machine.
0
entities on the wire
In the HTTP integration test the upstream received zero real entities. The egress guard fails closed if any survive.
10 / 10
restored, both modes
The client reversed all ten entities in non-streaming and one-character-per-delta streaming alike — byte-identical.
HTTP 200
live against the real API
A genuine Claude Haiku 4.5 call returned the real values reversed from a real streamed response: 74 in / 30 out tokens.
+12ms
mean added latency
Measured in eval/ci.py: redaction recall 1.0 on, 0 surrogate leak-back, and a tamper-evident hash-chained ledger.
The surrogate scheme is engineered so the model never notices, the substitution never corrupts a payload, and nothing sensitive can slip out by accident.
Referentially coherent
A name maps to the same surrogate on turn 1 and turn 50. The model can reason about “Brightmere Supply” across a long session because the alias never drifts — and byte-stable prefixes keep prompt caching hitting.
JSON-safe by construction
Surrogates use only characters that survive JSON escaping, so substring replacement is safe even inside a split streaming fragment. No quotes, no backslashes, nothing that shifts under serialisation.
The key stays local
The bijective map lives in an AES-256-GCM encrypted store on your machine, keyed from a local keyfile generated on init. The mapping never travels with the request. Lose nothing to the network.
Leak-back detection
Surrogates carry a subtle signature, so a scanner can spot any that slip into your working tree — and collisions against your real vocabulary or known brands are checked and reseeded at generation time.
Audit ledger
Proof of what categories left the building.
Every request appends a hash-chained, append-only record: timestamp, model, destination, bytes in and out, and a count of redactions by category — never the values themselves. A single command verifies the chain end to end. It is the artefact your CISO can take to the audit committee.
We would rather tell you the limit up front than have your security team find it in review. The firewall protects nouns. It does not hide that work is happening, or what kind.
Lane 1 · Semantic Firewall
Protects the names, not the shape of the work.
The structure is the point — it is what the model needs to be useful. So the model still learns that you run a multi-tenant billing system in TypeScript with a Postgres ledger and a quota bug. It just never learns whose. For the vast majority of agentic coding work, that is exactly the right trade: full capability, zero identifying IP on the wire.
Right when the secret is referential — names, IDs, hosts, keys, PII.
Not a fit when the algorithm or architecture itself is the secret.
Image content and novel structure are flagged, not silently trusted.
Lane 2 · When structure is the secret
Attested confidential-compute enclaves.
When the architecture, the model weights, or the algorithm itself cannot be revealed even in shape, pseudonymising nouns is not enough. That work belongs in a hardware-attested enclave where the inference runs against memory the provider cannot read, with a remote-attestation proof you can verify. It is a heavier, more expensive lane — and we will tell you honestly which of the two your problem needs.
Let the model help — without the leap of faith.
We are running early pilots of the Semantic Firewall with teams who want agentic coding on sensitive repositories. Most start with a 45-minute conversation: your threat model, what counts as a noun in your world, and whether Lane 1 is enough.