← Back to all articles
Challenges

The Day Your Agent Got Tools, Prompt Injection Became an Ops Problem

By Marc Molas·July 17, 2026·7 min read

A chatbot that gets tricked into writing a poem about your competitor is a screenshot on social media. An agent that gets tricked into emailing your customer database to a stranger is a breach disclosure. The difference between those two incidents is one architecture decision: you gave the model tools.

I come from enterprise operations, where we spent years building least-privilege access, egress controls and audit trails around every service account. What I see now, reviewing agent deployments, is those controls quietly waived for the newest and least predictable identity on the network — because the agent demo worked, and nobody re-ran the threat model between the demo and production. We've written before about what happens when there's no human at the keyboard; this post is about the blast radius that identity carries once tools are attached.

The industry has already produced the vocabulary and the proof. It's worth taking both seriously.

The lethal trifecta: private data, untrusted content, an outbound channel

In June 2025, Simon Willison named the pattern that turns an agent into an exfiltration engine — the lethal trifecta: access to private data, exposure to untrusted content, and the ability to communicate externally. Any two of the three are manageable. All three together mean a single poisoned document, email or web page can instruct your agent to gather sensitive data and send it out — with no vulnerability in your code, no compromised credential, no user clicking anything.

The reason this is structural rather than a bug: an LLM has no reliable boundary between instructions and data. Everything in the context window is, to the model, potential instruction. Thirty years of injection defenses — parameterized queries, output encoding — assume you can separate the command channel from the data channel. Inside a transformer's context, you can't. OWASP has ranked prompt injection as the #1 risk in its LLM Top 10 since the list existed, for exactly this reason.

That's also why "we hardened the system prompt" is not a security control. Instruction-hierarchy training and injection classifiers lower the hit rate; none of them takes it to zero. Against an attacker who can iterate freely against your public-facing agent, a filter that catches 99% of attempts is a delay, not a defense.

EchoLeak was the proof: zero clicks, CVSS 9.3

If the trifecta sounds theoretical, EchoLeak (CVE-2025-32711) ended the argument. Disclosed by Aim Security in June 2025 and scored at 9.3, it was a zero-click exfiltration chain against Microsoft 365 Copilot: a crafted email carrying hidden instructions sat in the victim's inbox until Copilot processed it during normal use, at which point the assistant retrieved other private content from the user's context and leaked it outward through auto-fetched resources. No user interaction. No malware. The trifecta, assembled in one of the most heavily engineered AI products on the market — Copilot reads your mail (private data + untrusted content) and renders rich output (outbound channel).

Microsoft patched it server-side, and no in-the-wild exploitation was confirmed. But the lesson isn't about one product. It's that a vendor with effectively unlimited security budget shipped the trifecta to hundreds of millions of seats, and the fix required redesigning trust boundaries, not tightening a prompt. We saw the same class of attack from the hiring side when a LinkedIn bio with an embedded flan recipe sailed through an automated recruiting pipeline — different domain, same root cause: untrusted text treated as trusted instruction.

You can't filter the attack, so you cap the consequence

Once you accept that some injection will get through, the engineering question changes from "how do I detect attacks" to "what can the agent do when it's compromised". That's a question operations people have answered before — it's the assume-breach model, applied to a component that is designed to follow instructions in its input. The controls, in the order I'd implement them:

Least privilege per tool, not per agent. The agent as a whole doesn't get a scope; each tool call gets one. The retrieval tool gets a read-only token scoped to the collections this user can see. The email tool can send to internal domains only. The database tool gets a role that can't touch PII tables. When the agent is deceived — plan for when — the injected instructions inherit these ceilings, and "exfiltrate the customer table" fails on permissions like any other unauthorized query.

A human gate on irreversible actions. Sending external email, moving money, deleting records, merging code: these tool calls return a pending approval, not a result. The reviewer sees a one-line description of the action before it executes. Boring, and it converts a breach into a declined request.

Sandboxed execution. If the agent writes and runs code, that code runs in a disposable container with no ambient credentials and an egress allowlist. The allowlist is the direct counter to the trifecta's third leg: an agent that can only reach your own APIs has nowhere to leak to. Egress filtering is 2005-era network hygiene, and it neutralizes the most dangerous capability an injected agent has.

Taint the untrusted input. Track which parts of the context came from outside — web pages, inbound email, user uploads — and restrict what tool calls can follow from them. Several research proposals formalize this (dual-LLM patterns, control/data-flow separation); even a crude version, like refusing high-privilege tool calls in turns dominated by fetched web content, removes the easiest chains.

Your tool registry is a supply chain

The Model Context Protocol made tools composable, which is genuinely good, and it created a new dependency class nobody's scanner covers. An MCP server is remote code your agent trusts — and its description text enters your context window, which means a malicious or compromised server can inject instructions through the tool metadata itself before any tool is even called.

Treat the registry like a package manager, because that's what it is: pin server versions, review what changed on upgrade, and allowlist the servers you've read rather than installing whatever the directory suggests. The npm ecosystem taught us what happens when trust in a registry is ambient. There's no reason to relearn it with components that hold live credentials.

What I'd do this quarter if I were your CTO

  1. Map your trifecta. For each agent: what private data can it read, what untrusted content reaches its context, what outbound channels exist. Any agent with all three is your priority — break the leg you can live without.
  2. Rotate agent credentials to per-tool scoped tokens. If your agent authenticates with anything resembling an admin key, this is the week's work that matters most.
  3. Put an approval gate on every irreversible tool. External sends, writes to production, payments. Measure how often the gate declines — that number is your incident count in the world where you hadn't built it.
  4. Add an egress allowlist to any environment where agent-generated code runs.
  5. Audit your MCP servers and tool descriptions like third-party dependencies: pinned, reviewed, allowlisted.

The honest caveat: most agent deployments will never face a live attacker, and an internal tool with no external content in its context can run with lighter controls — matching the control to the exposure is the job, not maximal paranoia everywhere. But "we'll add security once it matters" has a failure mode, and EchoLeak is what it looks like at 9.3 severity with zero clicks.

The model will follow instructions it shouldn't. That's not a flaw you patch; it's the operating assumption you engineer around — the same way we engineer around the fact that humans click phishing links. Agents don't need smarter filters. They need the boring, proven controls every other untrusted-input system already runs under.


If you're putting agents into production and want them built inside these boundaries from day one, that's what our AI operators do.

Ready to build your engineering team?

Talk to a technical partner and get CTO-vetted developers deployed in 72 hours.