LLM agents that act as the user
An AI assistant that can never see more than the person asking it.
By: Benjamin Clark
Intent
This pattern assumes a three-tier architecture, with a backend API between the UI and the data that enforces who can see what. It has an assistant's tools call that API with the caller's credentials. This enables two outcomes:
- The assistant can never see more than the person asking.
- It inherits the permissions, validation and auditing the API already has, rather than reimplementing them.
Motivation
An assistant usually reads data through a service account of its own, or a tool that lets the model decide what to read. Its access is then broader than any one user's, and only the prompt keeps users' data apart. It's a confused deputy: one prompt injection, and it reads data for someone who has no right to it.
This pattern takes that access away. The assistant's tools use the endpoints the UI already uses, with the caller's own credentials, so the API's rules apply as they are, and the model never chooses whose data to read. It sets the scope for the capabilities and safeguards an agent is built from.
Applicability
Use this pattern when:
- An AI assistant needs to read a platform's data.
- Each user may see only part of that data.
- An API already enforces what they can see, whether through tenants, roles or per-record rules.
Do not use this pattern when:
- No API enforces the permissions yet, since the assistant would have nothing to inherit.
- A run has no user, such as one triggered by an event. Scope the tools to one resource instead.
Structure
Participants
| Participant | Role |
|---|---|
| User | Asks the question, and holds the token that says what they may see. |
| Assistant handler | Builds the API gateway from the request's token, and runs the assistant. |
| Model | Decides which tools to call, and never chooses whose data they read. |
| Assistant's tools | Read through the API gateway. |
| API gateway | Built per request, and forwards the caller's credentials unchanged. |
| Platform API | Enforces tenants, roles and record rules, for the UI and the assistant alike. |
Constraints and trade-offs
- Permissions limit what the assistant can see, not what it says. Language models are non-deterministic, so it can misread data it's allowed to read, make something up, or give a different answer to the same question. People need to be able to check an answer against the data behind it.
- Every tool call is an API round trip, on top of the model's own, which adds latency.
- The assistant can only do what the API exposes. A question the API can't answer needs a new endpoint rather than a cleverer prompt, which is also the point.
Part of how I deliver
Where your API already holds the rules, I use this to keep them in charge. It's one of many patterns I draw on through contract delivery, working alongside the ones that shape how the assistant itself is built.
AI in your systems, safely
I put chatbots and MCP servers into the systems businesses already run, reaching only what they should. If you want one on yours, book a call and we'll talk it through.
