DEV Community

Ikkun
Ikkun

Posted on • Originally published at trustless-security.com

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

  1. 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.

  2. 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.

  3. 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.

  4. 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
single-binary 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.

Top comments (0)