Data exfiltration via AI agents: paths you haven't considered
Security reviews of AI agents tend to fixate on one channel: the model’s final response, transmitted to a third-party API. That is the channel the headlines describe, and it is usually the one your DLP covers. The exfiltrations that actually happen use the other paths — the ones that look like normal behavior until someone audits what the agent touched.
The tool call payload itself
An agent does not need to print a secret to leak it. It can pass the value as an argument to any tool: a shell command, an HTTP request, a file write. If the agent can call a tool that sends data somewhere — a curl command, a webhook — the secret leaves in the tool call, never appearing in model output at all. Output filtering alone never catches this: the payload bypasses the model’s text entirely.
Verbose tool output and error messages
Tools echo their environment back at you: env in a debug script, a
connection string in an error trace, a config dump in verbose mode. The
agent reads stdout and stderr as context, so a secret that a tool prints
becomes agent-visible even if the model never asked for it. Encodings make
this worse — a value base64- or URL-encoded in output looks like noise to a
human reviewer and like data to the model, which can decode it on request.
Log files and terminal scrollback
Secrets land in logs through routine accidents: a debug run, a failed startup, an env dump piped to a file. The agent’s log-reading tool then surfaces them to the model, and from there they are one tool call from leaving the machine. Terminal scrollback and shell history are the same risk, and agents increasingly have tools to inspect them.
Rich content side channels
Anything that makes the agent fetch or render content is a potential exfiltration pipe. A markdown image URL, a link preview, a documentation fetch that resolves an attacker domain — each is a network request the agent makes on the attacker’s behalf. DNS lookups and TLS SNI are classic side channels: the value may never appear in any request body, only in the domain being resolved.
Tool results and MCP responses
A compromised or malicious MCP server can request data from the agent under the guise of a legitimate operation, or return content engineered to steer the agent into echoing its own context back. The response channel is bidirectional: it delivers both data out and instructions in.
Local state as a staging area
Before anything leaves the network, it often passes through local state: temp files, caches, clipboard writes, git history. An agent that writes a value to a temp file has exfiltrated it if anything else on the machine — or a later sync — reads that file.
Where each path can be stopped
Every path crosses a boundary you can control:
- Spawn time: keep secrets out of context; inject them into the subprocess environment at execution and sanitize agent-visible stdout and stderr, including encoded variants.
- Transport: proxy HTTP tool traffic per host so the agent never handles credential material, and terminate TLS locally so verification stays real.
- Egress: run outbound LLM traffic through a DLP layer — keyword pre-filter, regex rules, then entropy scoring — that masks secret-shaped strings before they leave the machine.
- Record: an audit log of tool calls, proxy injections, and denials turns “did anything try to leave?” into a queryable question.
trustless covers the spawn, transport, and egress boundaries in one binary — process-level injection with output sanitization, a per-host credential proxy, and a DLP reverse proxy with 40 gitleaks-derived rules. Architecture details are in the docs.
If your agent’s output were clean but one of these side paths were open, how would you notice — and which path would you audit first?