SSOGEN / Learn / The Confused Deputy Problem: From a 1988 Compiler to AI Agents
Learn
The Confused Deputy Problem: From a 1988 Compiler to AI Agents
The confused deputy problem is a program with more authority than its caller being tricked into using it for that caller; the fix is the caller's authority.
Updated

The confused deputy problem is a flaw where a program (the deputy) holds more authority than the party asking it for something, and the asker gets the deputy to use that authority on its behalf. The deputy is neither malicious nor broken. It cannot tell whose authority a request should run under, so it uses its own.
The same mistake appears in:
- a 1988 compiler;
- cloud services that call each other;
- OAuth proxies;
- AI agents that call tools.
Hardy’s original case: a compiler and a billing file
Norm Hardy described the problem in “The Confused Deputy (or why capabilities might have been invented)”, ACM SIGOPS Operating Systems Review, volume 22, issue 4, October 1988. Wikipedia’s summary of the paper (read 2026-10-11) gives the case.
A compiler on a timesharing system let users name a file for debugging output. The compiler itself had permission to write statistics into a system directory. A user named the system’s billing file as the output file:
- The user had no right to write the billing file.
- The compiler did, and it used its own right.
- The billing data was overwritten.
The compiler checked what it was allowed to do, never what the caller was allowed to do.
Hardy’s fix, as the same summary puts it, is to bundle the designation of an object with the permission to use it.
The caller passes a capability, such as an open file handle, and the deputy can act only on what it was given.
Where the same flaw appears today
The details change but the pattern stays the same: a caller with little authority reaches a valuable resource through a deputy with broad authority.
| Scenario | The deputy | Authority it wrongly uses | Control that prevents it |
|---|---|---|---|
| Hardy’s compiler | The compiler | Its write permission on the billing file | Pass the caller’s capability, not a name |
| AWS cross-account role | A third-party service that assumes a role in your account | The role ARN another customer also supplied | A unique ExternalId in the role’s trust policy |
| AWS cross-service access | A service principal such as CloudTrail | The bucket policy’s trust in that service | aws:SourceArn or aws:SourceAccount conditions |
| MCP proxy to a third-party API | The MCP proxy server | A consent cookie tied to its static client ID | Per-client consent and exact redirect URI matching |
| Token passthrough | An MCP server | Tokens it accepts without checking they were issued to it | Audience validation; refuse tokens meant for others |
| AI agent calling tools | The agent | A shared or broad credential that outranks the person | A delegated credential with the person as subject, the agent as actor, narrow scope |
The AWS and MCP rows come from the vendors’ own documentation, cited below. The last row is our reading of how the same pattern applies to agents.
Cloud services: external IDs and source conditions
AWS’s documentation on the confused deputy problem (read 2026-10-11) describes two cases.
Cross-account access
You hire a monitoring company and give it a role to assume. Another of its customers learns or guesses your role ARN, which AWS notes “isn’t a secret”, and asks the company to use it.
The company then assumes your role for the wrong customer. The fix is an external ID:
- The company generates a unique value per customer.
- You put it in the role’s trust policy as an
sts:ExternalIdcondition. - The company sends the matching value on every call.
The other customer cannot change which ID the company sends.
Cross-service access
A bucket policy that trusts cloudtrail.amazonaws.com with no conditions would accept logs from an unauthorized actor in another account who knows the bucket name.
AWS recommends the global condition keys wherever a service principal gets access. With them, the policy checks whom the service acts for.
aws:SourceArn. A global condition key AWS recommends for service principals.aws:SourceAccount. A global condition key AWS recommends for service principals.aws:SourceOrgID. A global condition key AWS recommends for service principals.aws:SourceOrgPaths. A global condition key AWS recommends for service principals.
A worked example with fictional names: Acme’s bucket acme-audit-logs trusts a log service. Without a condition, any tenant of that service who knows the name can write to it.
Adding "aws:SourceAccount": "111122223333" limits writes to logs the service produces for Acme’s account.
OAuth proxies and MCP
The MCP security best practices page (specification 2026-07-28, read 2026-10-11) names the problem for MCP proxy servers. It is exploitable when all four conditions hold:
- the proxy uses a static client ID with a third-party authorization server
- clients can register dynamically
- the third-party server sets a consent cookie after the first approval
- the proxy skips its own per-client consent
The attack:
- An attacker registers a client with a malicious redirect URI and sends the user a link.
- The consent cookie makes the third-party server skip the consent screen.
- The authorization code goes to the attacker.
The specification is direct: proxy servers “MUST implement per-client consent”. The consent page must name the client and show the requested scopes and the registered redirect URI. Redirect URIs must match exactly, with no patterns.
Token passthrough
The second MCP form is token passthrough.
The authorization section says servers “MUST validate that access tokens were issued specifically for them as the intended audience” and “MUST NOT accept or transit any other tokens.”
Audience restriction comes from RFC 8707, resource indicators (read 2026-10-11), whose premise is that an access token must be valid only at a specific protected resource.
The full flow is in MCP authentication.
AI agents acting for people
An agent that calls tools is a deputy by design, and the two common shortcuts both repeat Hardy’s compiler:
- On the person’s own token, the agent can do anything the person can.
- On a shared service key, a person with little access can ask the agent for data they should not see, while the system sees only the agent.
RFC 8693 (read 2026-10-11) gives the words for the fix.
Under delegation, A “still has its own identity separate from B” and “any actions taken are being taken by A representing B”.
The act claim (section 4.1) is how a token says so.
A fictional token for Acme:
{ "iss": "https://login.acme.example", "sub": "maria.lopez", "act": { "sub": "agt_inv01" }, "aud": "https://invoices.acme.example/api", "scope": "invoices.read"}subis Maria.actis the agent.audis the one service that may accept the token.scopeis what the token allows.
The invoices API can then check Maria’s rights and the agent’s, and log both. OAuth token exchange covers how to obtain such a token.
The token changes nothing unless the resource server checks aud, scope and act. Without those checks, delegation reads as impersonation.
What to check in your own systems
- Does every service that acts for someone get that someone’s identity, not just its own?
- Does each token name one audience, and does each server refuse the others?
- Do you record consent per client, not per user or per cookie?
- Does every trust grant to another service carry a condition naming whom it acts for?
- Can one log line tell you both the person and the program?
How SSOGEN applies this to agents
The credential SSOGEN issues to an AI agent names the person in sub and the agent in act.
- One application. It covers one application and its scopes.
- Short life. It lasts 240 seconds by default, never more than 270.
- Consent first. The person first approves the agent on a consent screen.
- Scope on every call. The Gateway checks scope on every tool call.
- No passthrough. The Gateway never forwards the agent’s token to your server, so token passthrough cannot occur.
The scopes you grant set the boundary: once an agent may read data, what it does with that data is governed by those grants. See AI agent identity and the MCP Gateway.
Questions people ask
What is an example of the confused deputy problem?
What is the confused deputy problem in AWS?
How does the confused deputy problem apply to MCP?
How do you prevent the confused deputy problem for AI agents?
Where to go next
- Learn hub. Start here.
- MCP authentication and OAuth token exchange. For the OAuth side.
- Agentic AI security. For the wider risk picture.
Sources, all read 2026-10-11: Wikipedia, Confused deputy problem (for Hardy’s 1988 paper), AWS IAM User Guide, The confused deputy problem, MCP specification 2026-07-28, Security Best Practices, MCP specification 2026-07-28, Authorization, RFC 8707, RFC 8693.