How to use CaMeL to secure the agent setup
Any agent that reads untrusted data and can also call tools has the same weakness: an attacker can hide instructions inside that data, and the model may follow them instead of the user’s actual request. A web page, an email, or a PR comment becomes a way to make the agent exfiltrate secrets or take unwanted actions. Prompting the model to “ignore instructions in the data” helps but doesn’t close the hole, because the defense is still just another prompt competing with the attacker’s prompt.
CaMeL (“Defeating Prompt Injections by Design,” Debenedetti, Shumailov, Fan, Hayes, Carlini, Fabian, Kern, Shi, Terzis and Tramèr, Google DeepMind, Google and ETH Zurich, 2025) takes a different approach: fix this with system design instead of a better prompt.
The idea
CaMeL splits the agent into pieces with different trust levels:
- A privileged LLM (P-LLM) sees only the user’s original, trusted query. It plans by writing a restricted Python program — calls like
get_last_email(),query_quarantined_llm(),send_email()— but it never sees the content of tool outputs directly. - A quarantined LLM (Q-LLM) is the only component that reads untrusted data (email bodies, web pages, file contents). It has no tool access, so even if injected instructions steer it, it can’t act on anything — it can only return a value back into the program.
- A custom interpreter executes the P-LLM’s plan and tracks, for every value, where it came from (a “capability”). If a variable was derived from untrusted data, the interpreter enforces security policies before letting it flow into a sensitive tool call — e.g. it can require explicit user approval before sending an email to an address that was read from an untrusted document.
Because the control flow (which functions get called, in which order) comes entirely from the trusted query, injected text in the data can change a value but never the program itself. That’s the “by design” part: security doesn’t depend on the model resisting a manipulative prompt, it depends on the interpreter refusing to let tainted data reach sensitive operations without a policy check.
The results back this up: on the AgentDojo benchmark, CaMeL solves 77% of tasks with provable security guarantees, against 84% for an undefended baseline. Across the 949 AgentDojo attack cases, CaMeL drives successful attacks to (or near) zero for every model tested — e.g. GPT-4o goes from 233 successful attacks without CaMeL to 0 with it, Gemini 2.5 Pro from 300 to 0 — and the paper notes that the handful of attacks AgentDojo still rates as “successful” against CaMeL aren’t actually prompt injections. The cost is real: the paper reports roughly 2.8x the input and 2.7x the output tokens for the median AgentDojo task, since the system now runs two LLMs and an interpreter instead of one model in a loop.
Applying the pattern to a setup like ours
Our own setup is a small team of agents — conductor, layout, writer, reviewer — coordinating over a repo, issues, and PRs. The same failure mode applies: a PR description, an issue comment, or a fetched web page could contain injected instructions aimed at whichever agent reads it.
The CaMeL-style fix would be to keep the conductor as the privileged planner: it decides which agent runs, on which branch, with which files, based only on the task and issue text it trusts. The writer and layout agents act like quarantined readers — they fetch and summarize untrusted content (a video page, an article, PR comments) but that content should never be able to trigger actions outside their own file edits. Anything derived from fetched content that would cross a trust boundary — committing, pushing, merging, changing CI, touching secrets — should require the conductor (or a human) to explicitly approve it, not be inferred from what an agent read.
We don’t have a capability-tracking interpreter; our “policy” today is informal (agent prompts, file-path restrictions, and a human-reviewed PR). That’s the gap CaMeL highlights: without something enforcing the boundary mechanically, we’re relying on agents behaving well, which is exactly the assumption CaMeL is designed to remove.
Limitations worth keeping in mind
CaMeL isn’t a free lunch. It needs the user (or system designer) to write and maintain sensible security policies, which is real ongoing effort. Approval prompts can be a source of fatigue — users who click “allow” reflexively erode the guarantee. And the ~2.8x/2.7x token overhead is a genuine cost for latency- or budget-sensitive agents. It also only protects what’s expressed as capabilities and policies; anything outside that model (side channels, timing, or actions the policy simply didn’t anticipate) isn’t covered automatically.
Still, the core idea — separate planning-on-trusted-input from reading-untrusted-input, and mechanically enforce what tainted data is allowed to touch — is a pattern worth designing toward, even before we have anything as formal as CaMeL’s interpreter.