Transparent relay
Apart from the real↔mock substitution, forwarding keeps requests and responses completely unchanged — behaviorally identical to a direct connection.
The local Agent Harness (claude-code / opencode / hermes-agent and friends) does your work by stuffing material wholesale into the prompt — code, configuration, terminal output, along with the passwords, private keys, tokens, and cookies in them, all delivered to the LLM vendor’s servers.
Once that data leaves your machine, it is out of your control: it may end up in LLM vendor logs, be used for model training, or leak in a breach. And “never put Secrets in the context” is simply not viable in Agent workflows — credentials are exactly what an Agent tool needs to act on real systems on your behalf. Secret Guard resolves this tension: your Agent tools keep working with your Secrets, while the LLM never touches a real value.
Secret Guard is an ultra-lightweight local LLM Gateway. Point your Agent tool’s API BASE URL at it — the only integration cost is one line — and traffic flows through it to the LLM vendor:
Everything below comes from a real run: the gateway started with a minimal config (default strategy), protecting a fictional GitHub token — the only fiction here. Every other byte is the gateway’s real behavior.
Debugging a 401 on staging, you pasted your terminal output to your Agent tools — and the GitHub token from your environment ended up in the context. Without Secret Guard the two panels below would be identical (on a direct connection every byte reaches the LLM vendor as-is); with it, the only difference is exactly the part you wanted to protect:
{
"model": "gpt-5.6",
"messages": [
{
"role": "user",
"content": "staging deploy keeps failing with 401 — is my token expired?\n\n$ ./deploy.sh\nERROR: unauthorized (401)\n\n$ env | grep -i token\nGITHUB_TOKEN=ghp_0123456789abcdefghijklmnopqrstuvwxyzreal secret"
}
]
}
{
"model": "gpt-5.6",
"messages": [
{
"role": "user",
"content": "staging deploy keeps failing with 401 — is my token expired?\n\n$ ./deploy.sh\nERROR: unauthorized (401)\n\n$ env | grep -i token\nGITHUB_TOKEN=2_9rr_61dr1lmv2wf15aotyyt262l3t9_2pt4uihfake secret"
}
]
}
The 40-character real value is replaced by an equal-length, same-charset realistic Mock — the LLM keeps debugging with it, none the wiser.
The gateway log leaves evidence for every forward (redactions=1 is the replacement count):
forward record_id=c36e4984-ffa5-45d7-96f8-10a157de1965 method=POST path=/o/openai-main/v1/chat/completions status=200 elapsed_ms=0 redactions=1 provider=openai-main streamed=false complete=true error=NoneThe LLM decides to verify the token itself — it grabs “the one it knows” from the context into a command and sends it back to your Agent tools. What the LLM vendor’s servers emit is the Mock; the command landing on your machine carries the real value, and authentication passes as usual:
{
"name": "bash",
"arguments": {
"command": "curl -s -o /dev/null -w '%{http_code}' -H \"Authorization: Bearer 2_9rr_61dr1lmv2wf15aotyyt262l3t9_2pt4uihfake secret\" https://api.github.com/user"
}
}
{
"name": "bash",
"arguments": {
"command": "curl -s -o /dev/null -w '%{http_code}' -H \"Authorization: Bearer ghp_0123456789abcdefghijklmnopqrstuvwxyzreal secret\" https://api.github.com/user"
}
}
Tool calls travel as stringified JSON on the wire; the name and arguments are extracted and formatted here for readability, with content unchanged. In plain-text replies the LLM likewise quotes the token it “sees” — by the time it reaches your machine, it has been restored too.
Every forward is recorded on the WebUI’s Records page — here is the request above as Records shows it (Secret positions highlighted as Mocks):

Figure: WebUI Records page — session timeline and request details (the LLM’s view).
Handing production traffic to a middleman process requires proof that it won’t get in the way. Secret Guard guarantees the following properties by design:
Transparent relay
Apart from the real↔mock substitution, forwarding keeps requests and responses completely unchanged — behaviorally identical to a direct connection.
Strictly reversible
Each Mock maps to exactly one real value; Restore is the exact inverse of Redact — tool calls carrying Secrets are never broken by the swap.
Deterministic Mocks
A given Secret keeps the same Mock across turns, preserving the LLM vendor’s prefix-cache hits — in normal sessions, hit rates and token costs are unaffected.
Property-tested
These properties are not mere claims — they are pinned down by property-based tests and end-to-end integration tests in the upstream repository, run in full on every release.
Unique Mock in Context
A Mock never matches any other content in the request, so responses are never wrongly substituted.
Multi-Provider Routing
Supports multiple Providers (OpenAI / Anthropic / Gemini / Ollama / Responses) with per-request model-pattern routing to different upstreams.