CaMeL: Defeating Prompt Injection Attacks in LLM Agents Through Capability-Based Security

LLM agents that interact with untrusted data sources are vulnerable to prompt injection attacks. CaMeL (CApabilities for MachinE Learning) solves this problem by wrapping the LLM in a protective layer that enforces security policies without modifying the underlying model.

The Problem with Current Defenses

When an LLM agent reads a compromised document or email, attackers can embed instructions that redirect the agent’s behavior. Existing defenses—delimiter-based spotlighting, prompt sandwiching, instruction hierarchy fine-tuning—rely on making the model itself robust. None provide formal security guarantees, and all regularly fail against adaptive attacks.

The Dual LLM pattern (Willison, 2023) improves on these approaches by separating planning from data processing: a Privileged LLM plans actions without seeing untrusted data, while a Quarantined LLM parses untrusted data without tool access. But this protects only the control flow. An attacker who compromises the Quarantined LLM’s output can still redirect data—substituting a malicious email address or filename—causing the plan to execute with attacker-chosen arguments.

How CaMeL Works

CaMeL extends the Dual LLM pattern with three interconnected components:

The Privileged LLM (P-LLM) translates user queries into Python code that expresses the intended control flow. It sees only the user query—never tool outputs or parsed data.

The Quarantined LLM (Q-LLM) parses untrusted data into structured output via a predefined schema. It has no tool access. Critically, it cannot communicate to the P-LLM what information it needs—only whether it has enough information to complete the task.

The CaMeL Interpreter executes the P-LLM’s code while tracking a data flow graph. Every value carries capability metadata: its provenance (which tool produced it) and its allowed readers (which recipients may receive it). Before each tool call, the interpreter checks security policies against these capabilities. A policy violation blocks execution and, in production, requests user confirmation.

1
2
3
4
5
6
7
8
9
# Example: The interpreter tracks that 'address' derives from an untrusted email source.
# The send_email policy then blocks sending to that address unless the recipient
# already has read access to the attached document.
email = get_last_email()
address = query_quarantined_llm(
    f"Find Bob's email address in {email}",
    output_schema=EmailStr
)
send_email(subject="Meeting tomorrow", body="...", recipient=address)

Security Policies in Practice

Policies are Python functions that inspect capability metadata before tool execution. A calendar policy, for example, verifies that event details (title, description, location) are readable by all participants—or that all participants come directly from the trusted user. If a prompt injection substitutes an attacker’s email as a participant, the policy blocks the calendar invite because the event data is not shared with that recipient.

This granularity matters. Coarse control flow restrictions block entire operation types. Capability-based policies allow legitimate operations while preventing specific data flows that violate security intent.

Results on AgentDojo

Evaluated against the AgentDojo benchmark across banking, slack, travel, and workspace task suites:

  • CaMeL solves 77% of tasks with provable security, versus 84% for an undefended system—a modest utility cost.
  • Successful attacks drop to zero across most models and suites. Gemini 2.5 Pro drops from 300 successful attacks to 0.
  • The remaining “successful” attacks fall outside CaMeL’s threat model: text-to-text attacks with no data flow consequences, not prompt injections.
  • Cost: CaMeL requires approximately 2.82× more input tokens and 2.73× more output tokens than native tool-calling—reasonable given the security guarantees.

Compared to other defenses using the same model (Claude 3.5 Sonnet), CaMeL achieves 0 successful attacks. The next-best defense, tool filter, allows 8.

Known Limitations

Side channels: CaMeL’s STRICT mode addresses indirect inference attacks where an attacker counts tool invocations inside a loop to infer a private variable’s value. Exception-based side channels—where halted execution reveals one bit about private data—are mitigated but not fully eliminated.

Data-requires-action tasks: When the actions to take depend on untrusted data (e.g., “do whatever the email says”), the P-LLM cannot generate a plan without reading that data—an inherent limitation of the Dual LLM architecture.

Underdocumented APIs: When tool output schemas are unknown, the P-LLM cannot parse results without delegating to the Q-LLM, which newer models handle better. Claude Sonnet utility on the travel suite improved from 25% (version 3.5) to 75% (version 4) with no changes to CaMeL.

User fatigue: Security policies that trigger frequently ask users for confirmation. Well-annotated tool outputs (like workspace email metadata) reduce trigger rates significantly.

What This Means for Builders

CaMeL demonstrates that LLM agent security need not depend on model robustness. By treating security as a system design problem—applying control flow integrity, information flow control, and capability-based access control around an untrusted model—you achieve formal guarantees that heuristic defenses cannot provide.

CaMeL complements rather than replaces model-level defenses. Combining both delivers defense in depth. The code is available at github.com/google-research/camel-prompt-injection.