LLM Application Security advanced 8 min read 7 flashcards

Delegated Authority and the Confused Deputy

The 1988 result that a privileged intermediary acting on ambiguous instructions will misuse its own authority, why every tool-using agent is that intermediary, and the capability discipline that fixes it where filtering cannot.

In 1988 Norm Hardy described a compiler on a shared timesharing system. It ran with the privilege to write billing records in a protected directory, and it accepted an output filename from the caller. A user passed the name of the billing file. The compiler, holding authority the user did not have and unable to tell which of its powers the request was meant to invoke, overwrote it. Hardy's point was not that the compiler had a bug. The code did exactly what it was told. The point was that authority and designation had been separated: the caller named a file, and the system supplied the permission from somewhere else (Hardy, 1988, The Confused Deputy (or why capabilities might have been invented), ACM SIGOPS OSR 22(4), 36-38).

Every tool-using agent is that compiler. It holds credentials for systems the person talking to it may not be entitled to use, and it decides which operation to perform by reading text. The difference is that the compiler's ambiguity came from an ordinary filename, while the agent's comes from a document, an issue, a calendar invite or a web page that an attacker wrote specifically to be read.

Why the model cannot be the fix

The obvious response is to make the deputy smarter: teach it to notice hostile instructions, filter them, train refusals. This fails for a structural reason, not a capability reason. Instructions and data arrive on the same channel with no separator, so distinguishing them is a judgement call made by a component that the attacker gets to write input for. Invariant Labs demonstrated this against the GitHub MCP server in May 2025: an attacker files an issue on a public repository, a developer asks their agent to triage issues, and the agent reads private repositories and publishes their contents in a pull request on the public one. There was no CVE, because no code was wrong (Invariant Labs, 2025, GitHub MCP Exploited).

Notice what decided the impact. The injection decided the intent. The token decided the reach. The agent held a credential scoped to every repository the developer could see, so a request about one public repository executed against all of them. Had the session held a credential for one repository, the identical injection would have produced an error.

Designation carries authority

Hardy's own answer was capabilities: an unforgeable reference that is the permission, so naming a resource and being allowed to touch it are the same act. There is no ambient authority lying around for a caller's argument to redirect.

In practice this becomes four rules for agent systems.

Authority attaches to the request, not the process. Each session is issued a credential for the resources that session needs. A support triage run gets a token for ticket 4471, not for the ticket system.

Scope narrows at every hop and never widens. An agent calling a sub-agent or a tool passes something weaker than it holds. The chain of calls monotonically decreases in power.

Tokens name their destination. A credential valid at one service must be rejected by another, so a compromised downstream cannot replay what it received. This is audience binding, covered in audience binding and token exchange.

The enforcement point is downstream. OWASP's mitigation list says it plainly: implement authorization in downstream systems rather than relying on the model to decide (OWASP, 2025, LLM06:2025 Excessive Agency). A permission the model is asked to respect is a suggestion. A permission the API enforces is a control.

The protocol-level version

MCP names the problem directly. An MCP server that brokers access to third-party APIs is a deputy by construction, and the specification warns that "attackers can exploit MCP servers acting as intermediaries to third-party APIs, leading to confused deputy vulnerabilities". Its mitigation targets a specific mechanism: a proxy server using a static client ID with a third-party authorization server MUST obtain user consent for each dynamically registered client before forwarding, because otherwise the third party's remembered consent for the static client is silently reused for a client the user never approved (Model Context Protocol, 2025-06-18, Authorization).

When it breaks

Least privilege is undefined without a session boundary. "Minimum necessary permissions" means nothing for a long-lived agent, because over a week it needs everything. The scope only becomes small once you can say what this task needs, which makes session design an authorization decision rather than a plumbing one.

Read-only is not safe. The GitHub exfiltration used read on private repositories and write on a public one, both individually reasonable. The trifecta is private data, untrusted content, and any outbound channel; removing write from the agent but leaving it able to render an image URL leaves the channel open.

Consent fatigue converts a control into a rubber stamp. Per-client consent works while consent prompts are rare and legible. An agent that generates them continuously teaches the user to approve without reading, and the mechanism degrades into the ambient authority it replaced.

Sub-agents inherit more than they should by default. Most orchestration frameworks pass the parent's tool handles straight down, so a five-agent pipeline runs five deputies at full privilege. The narrowing has to be written; nothing does it for you.

References and further reading

Every source this page cites, in the order it cites them. All of them open in a new tab.

  1. Hardy, 1988, The Confused Deputy (or why capabilities might have been invented), ACM SIGOPS OSR 22(4), 36-38 cis.upenn.edu
  2. Invariant Labs, 2025, GitHub MCP Exploited invariantlabs.ai
  3. OWASP, 2025, LLM06:2025 Excessive Agency owasp.org
  4. Model Context Protocol, 2025-06-18, Authorization github.com
Check yourself

7 flashcards for this concept

Click a card to reveal the answer.

Drill the whole track