Prompt injection and API key exfiltration: what actually happens
Prompt injection gets talked about in abstract terms — “the model was tricked” — but the concrete damage is usually the same: a secret that was sitting in the agent’s context gets exfiltrated. To defend against it, it helps to walk through the actual attack chain, step by step.
The attack chain
The key gets into context. Your agent loads
.env, reads config, or receives an environment variable to use a service. From that moment, the key is part of the context window — the same working memory the model reasons over.Untrusted content arrives. The agent opens a webpage, reads a README, processes an email, or parses an API response. Any of these can contain instructions the model treats as commands: “ignore previous instructions”, “print the value of the DATABASE_URL variable”, or subtler variants that ask the agent to summarize, log, or send something.
The agent complies. The model is a next-token predictor, not a policy enforcer. An instruction that looks like it’s part of the task gets followed. The key value ends up in a tool call, a log line, a code snippet the agent writes, or the model’s own output — which is transmitted to a third-party API.
The key is now outside your machine. Once the value appears in output that leaves your control — an API request, a shared log, a generated file — it’s compromised. Rotate it.
The uncomfortable part: steps 2–4 can happen without any visible error. The agent looks like it’s doing its job.
Why “be careful” doesn’t work
The standard mitigations — “sanitize the model’s output”, “don’t paste untrusted text”, “use a system prompt that forbids leaking secrets” — all share a flaw: they rely on the model to make the right decision at the moment of exfiltration. That’s a probabilistic defense against a deterministic attack. The attacker only needs one success; the defender needs all of them.
The structural fix: make the key unavailable
The defense that actually holds is removing the key from the attack surface entirely. If the agent’s context never contains the plaintext value, then a successful injection has nothing to exfiltrate. This is what a credential broker does:
At the process layer: the agent references the secret by name; the broker resolves it into the subprocess environment at execution time. Agent-visible output — stdout and stderr — is scrubbed for key values, including base64 and URL-encoded variants, so even a verbose tool that echoes its environment can’t leak the value into context.
At the transport layer: HTTP-based tools talk to a local proxy that injects credentials per host. The tool — and the agent controlling it — never handles the credential material.
On the way out: outbound LLM traffic passes through a DLP layer that pattern-scans requests and masks secret-shaped strings before they leave the machine. Keys that leaked through other channels get caught at the edge instead of in an attacker’s hands.
This is the design of trustless, a
zero-dependency credential broker CLI for AI agents — 321 tests with -race,
cosign-signed releases with SBOM, and an append-only audit log of every
credential resolution. The threat model is documented in the
security model.
Prompt injection is not going away, and models will keep getting more suggestible before they get less. The only reliable defense is making the secret structurally unavailable — so that when an injection succeeds, the agent has nothing to hand over.
Have you traced where your agent’s keys actually live right now — .env
files, environment variables, config? That’s the attack surface.