How to keep API keys out of your AI coding agent's context window
Your AI coding agent needs your API keys. To call a model provider, to push a
commit, to query a service — it needs credentials, and the standard way to give
them is to put them where the agent can read them: .env files, exported
environment variables, or config files the agent loads.
That means the keys live inside the agent’s context window. And the context window is not a safe place for secrets.
Why context windows leak
The context window is the agent’s working memory — everything it reads, every tool output, every file it opens gets processed there, and summaries of it get sent to a third-party model API. Two failure paths follow from that:
Prompt injection. A webpage, a README, or a pasted snippet can contain instructions the agent follows. If the context already holds a key, the injected instruction can exfiltrate it — in a tool call, a log line, or the model output itself.
Verbose tool output. Debug logs, environment dumps, and misbehaving CLIs echo secrets back to the agent. Most of the time nothing bad happens. “Most of the time” is not a security posture.
Both paths share one root cause: the key was in the context in the first place. So the fix is structural — make sure the agent never holds the plaintext value at all.
Layer 1: resolve secrets outside the agent
Instead of the agent reading the key, invert the flow: the agent references a secret by name, and a separate component resolves the value at the moment it’s needed. For subprocesses, that means injecting credentials into the child process environment without the agent seeing them, then scrubbing stdout/stderr so key values — including base64 and URL-encoded variants — never surface in agent-visible output.
For HTTP-based tools, the same principle applies at the transport layer: a local proxy injects per-host headers and query parameters, so the tool talks to the proxy and the proxy talks to the service with credentials attached.
Layer 2: DLP on the way out
Injection handles credentials the agent uses. It doesn’t cover keys that were already pasted into configs, or values that leak through other channels. A data-loss-prevention layer on outbound LLM traffic catches those: every request leaving the machine is scanned for secret-shaped patterns — keyword pre-filter, format regexes, and an entropy check — and matches are masked before the request goes anywhere. It works with any OpenAI-compatible endpoint, so it fits mixed local/cloud setups.
Layer 3: erase what already leaked
Prevention is never perfect. Session databases and logs accumulate key values
from past mistakes, and deleting a row doesn’t erase the data — SQLite keeps
indexed copies in FTS tables and remnants in free pages. The final layer is
retroactive scrubbing: two-layer redaction (known values plus patterns) over
session DBs and text files, with FTS rebuild and VACUUM so the bytes are
physically gone.
What this looks like in practice
This is exactly the design of trustless,
a zero-dependency credential broker CLI for AI agents. trustless run
injects and scrubs, trustless serve runs the outbound DLP, trustless dlp scrub-db handles retroactive erasure — one Go binary, reading your existing
pass or Bitwarden store with no migration. The full command reference is in
the documentation.
The principle is simple: the agent is an untrusted caller, and the broker is
the only component that ever touches a key. The details — 321 tests with
-race, cosign-signed releases with SBOM, an append-only audit log of every
credential resolution — exist because a credential tool that can’t prove its
own integrity isn’t worth installing.
How does your setup handle secrets today — .env files, exported variables,
or a broker? And have you ever caught your agent echoing a key in tool
output?