Build a leak-resistant AI gateway for a professional office
Six small TypeScript modules that sit between your staff and any model, each covered by a test. Plus the one gap that code cannot close.
In short
Put a gateway between staff and every model. It swaps identifiers for reversible placeholders, keeps confidential work on a local model, makes every write wait for a person, strips external links and images from answers, logs one hashed line per event and replays known leaks as tests. The six modules below are plain TypeScript, tested with Node’s built-in runner.

This tutorial turns the layers from our guide to the API-wrapper myth into code. Each module does one job, has no dependencies beyond Node, and comes with the test that proves it.
The code on this page is generated from the same files the tests run. If a file changes without the page, the test suite fails.
What we are building
Every request from staff goes through the gateway. It redacts, picks a model, checks any tool call, cleans the answer and writes an audit line. The vendor, if it is used at all, only sees placeholders.
1. Redact into reversible placeholders
Detectors return spans; redact swaps each span for a placeholder like [[EMAIL_1]] and keeps the original in a vault that never leaves the office. The same value always gets the same placeholder, so the model can still tell two people apart. restore puts the originals back into the answer.
The name list is the cheap, reliable detector most offices skip: export client, matter and deal names from your case or practice system and match them exactly. It catches “Project Falcon”, which no regex will.
2. Route by sensitivity
Three signals keep a request local: a confidential label on the document, a classifier score at or above 0.5, or any redaction at all. A label the gateway does not recognise also stays local. Failing closed is the point.
3. Confirm every write, allow listed domains only
An agent that can send email can send data. checkEmail never allows a send on its own: recipients outside the allowlist are refused, and everything else waits for a person to click confirm. Note the exact domain match, so office.example.evil.net does not pass.
4. Sanitise the answer
Indirect prompt injection works by getting the model to emit something the chat client fetches, usually an image whose URL carries data. The sanitiser removes every image, drops links to hosts that are not listed and replaces bare external URLs.
Writing the test for this module caught a real bug: the first version swallowed the full stop after a bare URL. The regex now stops before trailing punctuation.
5. One audit line per event
Each prompt, retrieval and tool call gets one JSON line: who, what, where it went, how many items were redacted and the decision. The raw text is never logged. Its SHA-256 hash lets you match a line to a document during an incident without storing the document twice.
6. Evals that fail on a regression
Every leak you have seen becomes a case: an input and the strings that must never come out. The set only grows. When someone drops a detector to fix a false positive, the run fails and names the case that reopened.
The gap this code cannot close
None of this runs when an employee pastes a client file into a personal chatbot on their phone. That gap closes with a sanctioned tool good enough to use, browser and device policies on work hardware, a one-page AI policy and short training. Our guide covers each.
If part of the work goes to a vendor, choose the plan with care. Our comparison of personal, business and API plans shows which train on chats and how long each keeps data. What a leak costs in law is on our AI data-leakage page.
Key takeaways
- Redact into reversible placeholders; the vault never leaves the office.
- Route anything uncertain to the local model: fail closed.
- Writes always wait for a person; recipients outside the allowlist are refused.
- Strip images and unlisted links from answers to stop injection-based leaks.
- Log counts and hashes, not text, and replay every known leak as a test.
Frequently asked questions
Why not use an existing DLP product?
If you already pay for one, use it as a detector: the gateway accepts any function that returns spans. What matters is where the gateway sits, between staff and every model, not which detector it runs.
Can one gateway serve a local model and a vendor model?
Yes. chooseModel returns local or vendor, and the request handler calls the matching client. Keep the vendor path on a business plan or API with a data processing agreement.
Where are the placeholders restored?
Inside the gateway, after the answer comes back and before the user sees it. The vault never leaves the office, so a vendor only ever sees [[EMAIL_1]].
How many leak cases does the eval set need?
Start with every leak you have seen or tested and add one per incident. The set only grows; a rule change that breaks an old case fails the run.
Sources
Pages we checked for the facts above, with the date we last read them.
- LLM01:2025 Prompt Injection — OWASP Gen AI Security Project, checked 2026-11-05
Indirect prompt injection and exfiltration through an inserted image URL, which the sanitiser targets. - Enterprise privacy at OpenAI — OpenAI, checked 2026-11-05
API data not used for training by default; DPA available for the vendor path. - How long do you store my organization’s data? — Anthropic Privacy Center, checked 2026-11-05
API inputs and outputs deleted within 30 days by default.
See it on one of your own workflows
We start with a demo on synthetic data: one office workflow, a local model and the gateway rules from these articles. Real client data comes in only after a written scope.
Book a demo on synthetic data
Tell us which workflow you want to speed up. The demo needs none of your real data.
- Fixed-scope quote — no obligation
- Reply within 1 business day
About the author
Paxa Media
Written by Paxa Media, a technology company based in Rijeka, Croatia. Price ranges in our guides are indicative; your quote depends on scope.
Why you can trust this
- Builds the kinds of systems described here — websites, web and mobile apps, automation and integrations
- Technology company based in Rijeka, Croatia
- Price ranges in these guides are indicative, not quotes; scope sets the final price
Keep reading
All tutorials →ChatGPT behind your own API does not keep client data private
An internal wrapper changes the interface, not where the data goes. Eight layers of defence, the leak each one misses, and why the last gap is a personal chatbot.
AI & automationWhere client data goes: personal AI, business plans, APIs and a local model
Same model, very different terms. What happens to a client file on a personal plan, a business plan, the API and a model on your own hardware, checked on the vendors’ pages.
AI & automationRun a Local AI Agent on Your Own Machine: OpenClerq in About 15 Minutes
A local administrative agent that never sends your files anywhere. Install it, start the gateway, make the first call, and understand what it is doing.