What AI agent authorization is, and why roles and scopes fall short
AI agent authorization is a runtime control that decides, for each tool call, whether this agent may perform this operation, with these arguments, on this record, for this person, right now. It comes after identity. AI agent identity proves who is calling; authorization decides what that caller may do. Both are parts of a wider AI agent security program.
Most agents get access the way services always have: a role, an API key or an OAuth scope such as billing:write. That answers one question: can this agent reach this system? For agents, the risk sits in five details a role can't see:
- The arguments. A $40 refund and a $4,500 refund use the same operation and the same scope.
- The record. Reading a support case is fine. Reading a sales case, or another customer's invoice, isn't.
- Who the agent acts for. An assistant acting for one employee shouldn't edit a colleague's records.
- The budget. Ten small refunds on one invoice can add up to one large one.
- The output. The agent may need a customer's email address but not their Social Security number.
Agents also follow instructions found in the content they read. A hidden line in a ticket can steer an agent toward a call its role technically allows. So the decision has to look at the call itself, and it has to be made outside the agent.
The inputs to a tool call authorization decision
Tool call authorization only works when each input comes from a source the agent can't edit. Here is what a complete decision considers.
| Input | Example | Source the decision should trust |
|---|---|---|
| Agent identity | support-triage, proven by a short-lived certificate |
A verified credential, never a name in the request |
| Operation | createRefund, not getInvoice |
The API definition or Model Context Protocol (MCP) tool name |
| Arguments | Invoice INV-1042, amount 450.00 USD |
The request, parsed and normalized |
| Record | INV-1042 belongs to customer C-77; case 88 sits in the sales queue |
The system of record, read by the enforcement point |
| Acting-for | The agent acts for a support lead | A delegation token or session bound to that person |
| Budget state | $1,900 already refunded on this invoice this week | A shared counter outside the agent |
| Approval | Finance approved this exact call, once | The approval service |
| Output | Return email and phone; mask birth date | Field labels set by the service owner |
Two rules follow. First, never trust a value because the agent sent it. If it claims the invoice belongs to the customer on the case, read the invoice and check. Second, keep requests and facts apart. Arguments say what the agent wants; the record, counters and approval state say what is true. Least privilege for AI agents depends on the facts.
Policy models for AI agent access control
Four families of policy model are in common use. Real deployments mix them: roles pick which tools an agent gets, and attributes or relationships decide each call.
| Model | How it decides | Fits agents for | Trade-off |
|---|---|---|---|
| Role-based (RBAC) | Roles map to permissions | Which tools a class of agent may call | Blind to arguments, records and acting-for; roles multiply |
| Attribute-based (ABAC) | Rules over attributes of subject, object, operation and environment | Amount caps, record fields, time windows | Attributes must be fresh and trustworthy at decision time |
| Relationship-based (ReBAC) | Checks a graph such as "this person owns this case" | "An assistant may edit only its own person's cases" | Relationship data must stay in sync; poor at numeric limits |
| Policy languages (Cedar, OPA) | An engine evaluates written policies over the request and supplied data | Combining the above in reviewable, testable rules | Another service to run; policy quality is on you |
The US National Institute of Standards and Technology (NIST) defines ABAC in SP 800-162 as a method where authorization is decided by evaluating attributes of the subject, the object, the requested operations and sometimes the environment against policy. A widely cited relationship-based system is Google's Zanzibar, described in a 2019 paper as "a global system for storing and evaluating access control lists."
Policy languages: Cedar and OPA
Cedar is a policy language built on permit and forbid statements. Its documented evaluation is simple: if any forbid is satisfied, deny; otherwise, if any permit is satisfied, allow; otherwise, deny. Default deny and forbid-wins are built in. One subtlety matters for security teams. If a policy's evaluation returns an error, Cedar skips it. A forbid that errors on a missing attribute stops protecting you without failing loudly. Test every forbid with examples that must be denied, and watch the diagnostics for erroring policies.
Open Policy Agent (OPA) is a general-purpose policy engine and a graduated Cloud Native Computing Foundation project. Its Rego language returns whatever decision your policy computes. Default deny and forbid-wins are conventions you write yourself, such as default allow := false, not built-in semantics. OPA's strength is breadth: one engine can check Kubernetes admission, API calls and agent tool calls.
Delegation, acting-for and the confused deputy
An agent that acts for a person holds two kinds of authority: its own and the person's. The confused deputy problem is what happens when it uses the wrong one. In Norm Hardy's original example, a user tricked a compiler into overwriting a billing file that only the compiler could write.
With agents, the agent holds a broad service key. A user, or text injected into a document, asks for something the user couldn't do. The agent does it with its own key. The OWASP Top 10 for Agentic Applications (2026), from the Open Worldwide Application Security Project, covers this confused-deputy pattern between agents under ASI03 Identity and Privilege Abuse, and recommends re-verifying each privileged step with a centralized policy engine. The OWASP agentic top 10 guide maps controls to each risk.
The fix is to decide on the intersection. Allow a call only if the agent may make it, the person it acts for may make it, and the record fits both.
Carrying the acting-for identity
OAuth 2.0 Token Exchange (RFC 8693) standardizes swapping one token for another. It separates two cases. With impersonation, the actor takes on all of the subject's rights. With delegation, "principal A still has its own identity separate from B." Delegated tokens carry an act (actor) claim, and chains nest. Prefer delegation, so logs show both the agent and the person. Microsoft Entra ID's on-behalf-of (OBO) flow solves the same problem for a middle-tier API that calls downstream with a user's delegated permissions.
Know the limits. RFC 8693 says prior actors in nested act claims are "informational only" for access control, so multi-hop agent chains need explicit policy. And a token says who is asking, not whether a $4,500 refund is reasonable.
Deny by default and forbid wins: a policy example
Deny by default means nothing runs unless a rule allows it. A new tool, a new operation or an unexpected argument shape is refused until someone grants it. Forbid wins means a small set of hard rules overrides every grant. If a broad permit and a forbid both match, the forbid decides. Together, these keep mistakes in grants from turning into incidents: a grant that is too wide still can't cross a forbid.
Here is a refund policy in plain English, using Northwind, a simulated company from AgentFort's lab demos:
- Support agents may issue refunds up to $100 without approval.
- Larger refunds need approval from Finance, and the person the agent acts for can't approve their own request.
- No more than $2,000 may be refunded per invoice per week.
- A refund must be for an invoice that belongs to the customer on the case.
- No agent may export or delete customer data.
The business owner writes this version. The enforced version must be precise and tested against examples before it goes live.
The same rules in Cedar-like syntax
This sketch is illustrative. Entity and attribute names are made up, and amounts are integers in cents to avoid unit mistakes.
@id("refund-small")
permit (principal in AgentGroup::"support-agents",
action == Action::"billing.createRefund", resource is Invoice)
when { context.amount_cents <= 10000 && context.currency == "usd"
&& resource.customer == context.case.customer };
@id("refund-approved")
permit (principal in AgentGroup::"support-agents",
action == Action::"billing.createRefund", resource is Invoice)
when { context.currency == "usd"
&& resource.customer == context.case.customer
&& context has approval
&& context.approval.approver in Group::"finance"
&& context.approval.approver != context.acting_for };
@id("refund-weekly-cap")
forbid (principal, action == Action::"billing.createRefund", resource is Invoice)
when { resource.refunded_this_week_cents + context.amount_cents > 200000 };
@id("no-export-or-delete")
forbid (principal,
action in [Action::"crm.exportCustomers", Action::"crm.deleteCustomer"],
resource);
Every attribute here must come from the enforcement point, not the agent. resource.customer and refunded_this_week_cents are read from billing. The approval is checked against the exact call before the policy sees it.
Where to enforce AI agent access control, and why credentials stay outside the agent
There are three places to put the check. Each sees different things.
| Where | What it sees | Strength | Weakness |
|---|---|---|---|
| Inside the agent (software development kit or framework hook) | The agent's plan and conversation | Easy to add; can ask the user in context | Protects one agent; runs beside code that may be compromised; the agent still holds the key |
| Gateway in front of the service | Every caller's request; can read records; holds the credential | One policy for every agent, including vendor and coding agents | Extra hop; needs record lookups; must fail closed |
| Inside the service | Full data and business rules | Most precise | Each team rebuilds it; hosted third-party and legacy services can't be changed |
The OWASP AI Agent Security Cheat Sheet says to enforce authorization "in the execution component, outside the agent's context." The deciding factor is the credential. If the agent holds the service key, any check on its path is advisory: a manipulated agent or a developer's script can call the API directly. Move the key to the enforcement point, and let the network route agents only to that point. In-agent checks still help with user experience. Keep your API gateway covers how this fits beside the gateway you already run.
Fail closed when the policy service is down
Every enforcement point eventually loses its policy source, so decide the behavior in advance. Failing open turns an outage into an incident. The OWASP cheat sheet says to fail closed when risk classification, approval validation, policy lookup or audit logging fails, and to fail closed for unknown tools. A workable middle ground is to keep the last signed policy for a short, fixed lease, then refuse every call until the source returns. Never let a cached policy live indefinitely, and don't cache decisions that depend on budget counters or approval state. Test it: stop the policy service in staging and confirm calls are refused once the lease ends. Log each refusal during the outage, so the gap leaves evidence rather than silence.
MCP authorization: what the spec covers and what it leaves to you
MCP is how many agents reach tools. As of October 2026, the current specification (version 2026-07-28) makes authorization optional. Over HTTP, it builds on the OAuth 2.1 draft:
- An MCP server is an OAuth resource server and must publish Protected Resource Metadata (RFC 9728).
- Clients must name the target server with the
resourceparameter (RFC 8707). - Servers must check that tokens were issued for them, and "MUST NOT accept or transit any other tokens."
- Servers should challenge for the scopes an operation needs; clients step up when asked.
- Servers on the local standard input/output (STDIO) transport take credentials from the environment instead.
The MCP security best practices call forwarding a client's token downstream "token passthrough" and forbid it.
This settles who is calling and with which scopes. It doesn't decide whether this tools/call, with these arguments, on this record, should run. The best practices list "treating claimed scopes in token as sufficient without server-side authorization logic" as a common mistake. Per-call checks are still yours. MCP security covers tool poisoning and server trust.
Checklist: least privilege for AI agents
Use this list to review any agent that can change data or move money.
- Give each agent its own identity and an accountable owner, and retire shared keys.
- Grant per operation, not per API or per scope.
- Add conditions on arguments and on the record, and have the enforcement point read the record.
- Record who the agent acts for, and allow a call only if both the agent and that person may make it.
- Start from deny by default, and write hard limits as forbid rules.
- Hold service credentials at the enforcement point, never in the agent.
- Restrict agent network access so the enforcement point is the only route.
- Mask response fields the agent doesn't need.
- Send high-impact calls to human approval and money-moving calls through spending limits.
- Fail closed, and test the failure.
- Expire grants, and remove access the agent hasn't used.
- Log every decision, including denials, as audit evidence.
How AgentFort handles this
AgentFort Access sits between agents and the services they call, over REST and MCP. Every call is checked: the agent's identity, the exact operation, its arguments and the record it touches, which AgentFort reads itself. Anything not granted is denied, and a forbid always wins. AgentFort calls the service with its own credential, scoped to that one operation, so agents never hold the service key. Over MCP, an agent sees only the tools it may use. Owners write rules in plain English; AgentFort compiles them into Cedar they can read, test and replay against past requests. If the control plane is unreachable, the gateway keeps the last signed rules for a short lease, then refuses every call. See AgentFort Access, watch a demo or become a design partner.
Frequently asked questions
What is the difference between authentication and authorization for AI agents?
Authentication proves which agent is calling, usually with a credential such as a short-lived certificate or a signed token. Authorization decides what that proven agent may do on this specific call: which operation, with which arguments, on which record and for whom. You need both. Strong authentication with coarse authorization still lets a correctly identified agent issue the wrong refund. Fine-grained policy with weak authentication can be bypassed by an agent posing as another.
Can a system prompt control what an AI agent is allowed to do?
No. A system prompt is an instruction to the model, not an enforced rule. Text the agent reads later, such as an email, a web page or a tool result, can override it, and the model can simply make a mistake. Use prompts to shape behavior and reduce noise. Put permissions in a policy that runs outside the agent, at a point that holds the credentials and can refuse the call.
How do I handle permissions when one AI agent calls another?
Treat every hop as a new request. The receiving agent should authenticate the calling agent, know which person the chain started from, and check its own policy before acting. Don't pass a full set of permissions down the chain; give the downstream agent only what its task needs. OWASP's ASI03 entry describes a low-privilege agent relaying instructions to a high-privilege one as a confused deputy, which per-hop checks are meant to stop.
Does per-call authorization slow AI agents down?
Rarely in a way users notice, because a policy check is small next to a model call. At very large scale, Google's Zanzibar paper reported 95th-percentile latency under 10 milliseconds while serving millions of authorization requests per second. In practice the main cost is fetching record data. Cache records briefly where slightly stale data is safe, and read fresh where it isn't, such as budget counters and approval state.
How often should AI agent permissions be reviewed?
Continuously, if you can. Compare what each grant allows with what the agent actually calls, and remove operations it hasn't used in a set period. Give grants an expiry so access lapses unless someone renews it. Review immediately when a service adds a new tool or operation, and keep it closed until its owner approves it. Annual or quarterly reviews built for human accounts are too slow for agents that change every week.
Sources
- Authorization, Model Context Protocol specification (version 2026-07-28)
- Security Best Practices, Model Context Protocol
- RFC 8693: OAuth 2.0 Token Exchange
- OWASP Top 10 for Agentic Applications for 2026
- OWASP AI Agent Security Cheat Sheet
- Cedar policy language: Authorization
- NIST SP 800-162: Guide to Attribute Based Access Control (ABAC) Definition and Considerations
- Zanzibar: Google's Consistent, Global Authorization System (USENIX ATC 2019)