What is the confused deputy problem?
By Identra · Updated
The confused deputy problem is a security failure in which a program holding legitimate authority is tricked into misusing that authority on behalf of a less privileged party. The attacker never steals the deputy's permissions directly; it supplies input that causes the trusted intermediary to act against its owner's interests.
Key numbers
- 1988: the year Norm Hardy named and documented the confused deputy problem (Hardy, ACM SIGOPS Operating Systems Review, 1988)
- May 2025: a malicious GitHub issue coerced an agent using the GitHub MCP server into leaking private repository data through a public pull request (Invariant Labs, 2025)
- The 2025-06-18 MCP specification made RFC 8707 resource indicators mandatory for MCP clients and banned token passthrough by servers (Model Context Protocol specification, 2025)
Where does the term come from?
Norm Hardy coined the term in a 1988 paper titled The Confused Deputy, published in ACM SIGOPS Operating Systems Review. The incident behind it happened at Tymshare, a timesharing company where Hardy worked. A compiler was granted permission to write to a billing file in its own directory so it could record usage statistics. A user invoked the compiler and supplied an output path for debug information that happened to point at that billing file. The compiler checked its own permissions, found the write allowed, and overwrote the billing records.
The compiler was the deputy: a program acting for two masters, its operator who trusted it with the billing file, and its caller who supplied the pathname. It could not tell which authority applied to which request. Hardy's subtitle, or why capabilities might have been invented, made the deeper point that identity-based access control invites this failure because permission attaches to the program rather than to the specific request.
Why is a 1988 problem relevant again?
The confused deputy pattern appears anywhere a privileged intermediary accepts input from less privileged parties. Cross-site request forgery is the classic web instance: the browser is a deputy carrying the user's session cookie, and an attacker's page tricks it into sending authenticated requests the user never intended. Cloud platforms hit the same wall with cross-account roles, which is why AWS added external IDs to its AssumeRole flow.
Agentic AI has now made the deputy pattern the default architecture rather than an edge case. An AI agent holds a user's credentials and simultaneously takes instructions from content it reads: web pages, tickets, emails, repository issues, tool responses. Every one of those inputs is a potential pathname pointed at the billing file. Most identities in modern environments are not human, and agents are among the fastest growing kinds, so the number of deputies is compounding.
How does it show up in MCP servers and AI agents?
In May 2025, Invariant Labs demonstrated the pattern against the official GitHub MCP server. An attacker filed a malicious issue in a public repository. When the victim asked their agent to review open issues, the agent read the attacker's instructions, used the victim's GitHub token to pull data from the victim's private repositories, and published it in a pull request on the public repository where anyone could read it. No code in the MCP server was broken. The agent did exactly what its inputs told it to do, with authority its inputs should never have commanded.
Indirect prompt injection is the modern equivalent of Hardy's pathname. The attacker does not need the token; the attacker only needs to get text in front of a deputy that holds one. The mapping to the 1988 case is almost exact.
| Element | 1988 Tymshare compiler | 2025 AI agent with MCP |
|---|---|---|
| Deputy | Compiler running with its own file permissions | Agent session holding the user's OAuth token |
| Legitimate authority | Write access to the billing file | Read and write access to the user's private repositories |
| Attacker input | Debug output pathname supplied by the caller | Instructions embedded in a public issue or tool response |
| Damage | Billing records overwritten | Private data exfiltrated through a public pull request |
What is OAuth token audience confusion?
OAuth creates its own family of confused deputies when tokens are not bound to a specific audience. If a token minted for service A is accepted by service B, then A can act as a deputy against B, replaying the user's credential somewhere the user never authorized. The same failure occurs when an intermediary such as an MCP server passes the token it received from a client through to upstream APIs, collapsing several distinct trust relationships into one bearer credential.
The Model Context Protocol addressed this directly in its 2025-06-18 specification revision. MCP servers are classified as OAuth resource servers, MCP clients must use RFC 8707 resource indicators so each token names the exact server it is intended for, and servers must not pass through tokens they receive. Audience binding means a stolen or misdirected token is useless anywhere except the one resource it was minted for, which removes a whole class of deputy confusion at the protocol level.
How do you prevent confused deputy attacks?
No single control eliminates the problem, because it is architectural: any intermediary that mixes authority from one party with input from another can be confused. Defense means shrinking what a confused deputy can do and detecting when it acts out of character.
- Bind every token to an audience. Use RFC 8707 resource indicators and validate the audience claim at each resource server.
- Never pass tokens through intermediaries. Each hop should exchange for a credential scoped to its own identity and purpose.
- Grant least privilege per task, not per deputy. An agent reviewing public issues does not need private repository scopes in the same session.
- Treat all retrieved content as untrusted input. Data an agent reads must never be able to silently escalate what the agent does.
- Tie authorization to the originating principal. Decisions should ask who asked for this action, not just what the deputy is allowed to do.
- Monitor deputies at runtime. A deputy that suddenly reaches resources outside its task pattern is confused, compromised, or both.
How Identra thinks about it
Better credential hygiene alone cannot solve the confused deputy problem, because the deputy's credential is valid at the moment of abuse. What fails is the link between authority and intent, and that link only exists at runtime. Every AI agent, service account, and workload is a deputy for someone, so the durable control is a runtime identity layer that knows which principal initiated each action, verifies that the authority being exercised matches the task at hand, and cuts off a deputy the moment its behavior diverges from the intent it was given.
Go deeper: The Non-Human Majority
Frequently asked questions
What is a simple example of the confused deputy problem?
The original 1988 case: a compiler had permission to write usage statistics to a billing file. A user asked it to write debug output to a path that pointed at that billing file. The compiler checked its own permissions, found the write allowed, and destroyed the billing records. The trusted program used its authority to serve the wrong master.
How is the confused deputy problem different from privilege escalation?
In privilege escalation, an attacker gains permissions they were never granted, breaking the access control system. In a confused deputy attack, no permission boundary is broken at all. The deputy legitimately holds the authority it exercises; the attacker simply supplies input that steers that authority toward the attacker's goal. Every check passes, which is why these attacks evade permission-based defenses.
Why are AI agents called confused deputies?
An AI agent holds its user's tokens and permissions while taking instructions from content it reads: web pages, emails, tickets, tool responses. When attacker-planted text in that content redirects the agent, it exercises legitimate authority on the attacker's behalf, which is exactly Hardy's deputy pattern. The agent architecture makes mixing trusted authority with untrusted input the default, not an edge case.
How do you prevent confused deputy attacks in OAuth?
Bind every token to a specific audience using RFC 8707 resource indicators, and validate the audience claim at each resource server so a token minted for one service is rejected everywhere else. Never let intermediaries pass received tokens through to upstream APIs; each hop should exchange for a credential scoped to its own identity, purpose, and downstream target.
