Hisham Alhussain
← All posts

Your agent will read something malicious. Plan for it.

· 2 min read

Here's something I tell every team building agents: at some point, your agent is going to read text written by someone who wants to mess with it. An email, a web page, a PDF, a support ticket, a calendar invite. If your agent processes outside content, that day is coming.

And there's no prompt you can write that fully fixes it. Prompt injection isn't a bug you patch. It's a property of how these models work. They don't reliably tell the difference between your instructions and instructions hidden in the data.

So instead of trying to make the model un-trickable, I design systems where a tricked model can't do much damage.

The dangerous combination

Simon Willison described this really clearly last year as the "lethal trifecta." An agent becomes dangerous when it has all three of these:

  • Access to private data
  • Exposure to untrusted content
  • A way to send data out (email, web requests, posting somewhere)

If an agent has all three, a malicious document can tell it to grab something private and send it somewhere. Take away any one of the three, and the risk drops a lot. That's my first design check on every agent now.

Least privilege, for real

This is old security advice, but it matters even more with agents:

  • Scope tools tightly. If the agent only needs to read one calendar, don't give it access to the whole workspace.
  • Read-only by default. Write access is the exception, and it needs a reason.
  • Separate credentials per agent. Not a shared admin token. If one agent gets tricked, the blast radius should be small.
  • Allowlist destinations. If the agent can make web requests or send messages, limit where they can go.

Enforce rules in code, not prompts

"Never send customer data to external addresses" in a system prompt is a suggestion. The same rule enforced in the tool code is an actual rule. If something really must never happen, make it impossible in code. The model can be convinced of anything. Your code can't.

Humans approve the irreversible stuff

Payments, deleting data, sending messages to customers, changing permissions. Anything that's hard to undo should need a human click, at least until you have a lot of evidence the system behaves. Show the human exactly what's about to happen, not a vague summary.

Be careful with MCP servers too

Every tool you connect is part of your attack surface. Third-party MCP servers can have tool descriptions that contain instructions, or can change after you installed them. Review them like any other dependency, pin versions, and don't connect things you don't need.

Test it like an attacker

I keep a small set of injection attempts in my eval suite: hidden instructions in documents, fake "system" messages in emails, requests to reveal the system prompt. It won't catch everything, but it catches regressions and keeps the team thinking about it.

None of this makes agents perfectly safe. But it moves you from "one clever email away from a disaster" to "a tricked agent can only do a small number of harmless things." That's a much better place to be.