Your users love it. Your demo killed it.
But here's the question nobody asked during the demo: whose permissions is the AI actually using?
If the answer is "its own", then you have a confused deputy problem.
Much of the current discussions around LLM security focuses on prompt injection, where attackers manipulate model instructions through crafted inputs. But in many cases, prompt injection is simply the mechanism that trigger confused deputy, tricking the AI system into misusing its own privileges on behalf of the attacker.
What is a Confused Deputy?
In traditional systems, this shows up when a privileged service performs an action for an unprivileged user without checking whether the user is authorized.
In LLM applications, the deputy is often your AI agent or the application acting on behalf of the model. It has a service identity such as an IAM role through which it can access databases, invoke APIs etc for backend system interactions. It needs this access to be useful. However, when a user asks a question, the system often retrieves information using the application-level privileges rather than the user's own permissions. This creates the classic conditions for a confused deputy problem.
The user just got a free upgrade to the agent's permission level.
A simple example :
Let's say your AI chatbot has a tool ( lambda function ) that it used to look up orders. This Lambda runs with an IAM role that has read access to the entire Orders table. It has to, because the agent serves all customers.
@tool
def get_order(order_id: str):
"""Look up an order by ID"""
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('Orders')
return table.get_item(Key={'order_id': order_id})Now Customer A asks:
"What's the status of order 5678?"
The agent calls get_order("5678"), the tool fetches it, and the agent responds with the status.
One problem though: 5678 belongs to Customer B.
Customer A just accessed Customer B's order with a perfectly normal-sounding question.
The tool never checked. The agent never checked. The IAM role doesn't know or care which customer is asking.
The uncomfortable truth
The confused deputy problem isn't a bug in your code. It's a design flaw in how many of the GenAI applications are built.
We give agents broad access because it's easy. We skip user-level authorization because frameworks don't enforce it by default. We trust the LLM to "do the right thing"… until it doesn't.
And here's what makes it truly dangerous: it doesn't require a sophisticated attacker.
No jailbreak. No prompt injection !
Just a normal question that the agent is happy to answer, because nobody told it not to.
Why this is worse than traditional Privilege Escalation ?
In a traditional web application, the backend checks the authenticated user's permissions before returning data. The API knows who is calling and enforces access control.
In an LLM application, a new intermediary; the agent sits between the user and the backend, potentially breaking this authorization chain.
The agent is a middleman with a master key. Every user gets to use that master key indirectly, by asking the agent nicely.
So… How Do You Fix This?
The short answer: the user's identity must follow the request all the way to the data source.
But that's easier said than done.
The fix isn't a one-liner, but rather an architectural shift. It involves rethinking how identity flows through your workflows, how tools validate permissions, how RAG systems filter results, and how you draw the line between what the LLM decides and what your code has enforced.
— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —
Next up in the series: GenAI Security Threats Demystified: Defending Against the Confused Deputy : Identity, Authorization, and the Architecture That Makes It Work.