Sitemap

AI Agents Calling Your APIs? Here’s How to Secure Them

--

Press enter or click to view image in full size

At some point in the last year, an AI agent probably hit one of your API endpoints. Maybe it was one you built yourself. Maybe it was a third-party agent that your users connected. Either way, most authorization models weren’t designed with that caller in mind, and the gaps are starting to matter.

The problem with human-centric authorization

OAuth 2.0 was designed around a human-initiated flow. A user authenticates and consents, and a token is issued. That token is usually scoped to whatever the user asked for, valid for the session, and issued once. This process works as long as a human is making the decisions.

AI agents break almost every assumption in that model. An agent receives an instruction and starts making API calls, sometimes dozens of them, across multiple services, on behalf of a user who initiated the conversation minutes ago. When an agent acts on behalf of a user, there are two identities in play: the agent itself and the user it represents. Most token architectures combine these, and that combination creates risk.

Most architectures issue a token at the start of a session and leave it at that. The agent gets what it needs for the first call — and everything else it might decide to do after that. Giving broad access at the beginning and assuming the agent will stay within a reasonable framework isn’t a security model; it’s an optimistic guess.

MCP authorization is not enough

If your team is working with Model Context Protocol, you’ve likely come across its authorization chapter. MCP authorization secures the connection between the MCP client and the MCP server, which is important but limited. For a deeper look at how to design APIs with MCP authorization in mind, see Design MCP Authorization APIs.

The token the MCP client uses to reach the server is not the right token for the API. If the MCP server simply forwards it downstream, you’re either granting that token unnecessarily high privileges upfront, or your API is making decisions based on a token that wasn’t designed for it. MCP authorization stops at the server boundary. Everything that follows, such as your actual APIs, your data, and your business logic, is outside its scope and still needs its own protection.

Use OAuth precisely: scopes and claims

OAuth is the right foundation. The main issue is that most implementations use it loosely and for agents, precision is important. Here are some recommendations:

Scopes for coarse-grained limits

Every agent token should carry scopes that reflect exactly what that agent needs for specific tasks. A token scoped to transactions:history should not also be able to create transactions. Limiting scopes should be the rule, not the exception.

Claims for fine-grained authorization

Scopes provide information to the API about what category of access is permitted. Claims tell it the specifics. A well-constructed agent token should carry everything the API needs to make a correct access decision at runtime:

{
"sub": "dana.demo",
"scope": "transactions:history",
"client_type": "ai-agent",
"client_assurance_level": "1",
"transaction_not_older_than": "2025-10-01",
"transaction_amount_limit": "1000",
"aud": "transactions-api",
"exp": 1718000000
}

A few things worth noting here. The client_type: ai-agent claim allows your API to:

  • differentiate agent traffic from human traffic
  • apply different authorization policies
  • produce audit logs that clearly attribute actions to the right kind of caller

The client_assurance_level reflects how trustworthy the agent client is: a confidential client with a workload identity gets a higher level than a public client that can’t securely store credentials. The aud field limits the token to a specific API, so it can’t be reused across services. And exp is short; agent tokens should expire quickly.

Token exchange for agent chains

Multi-agent chains are where token discipline usually breaks down. In a multi-agent system, a single user instruction can trigger a chain: an orchestrator agent calls a retrieval agent, which calls a summarization agent, which calls an action agent, each making API requests on behalf of the original user.

If each agent in the chain simply reuses the token it received, you’ve lost least privilege entirely. The token issued for the orchestrator carries whatever scope was needed at the top of the chain, and every downstream agent inherits it.

OAuth’s token exchange flow (RFC 8693) solves this. Here’s what it looks like in practice:

  1. The user authenticates, and the orchestrator receives a token with a broad delegated scope.
  2. Before calling the retrieval API, the orchestrator exchanges its token at the authorization server, requesting a new token with only documents:read scope, audience-restricted to the retrieval API.
  3. The retrieval agent uses that narrow token to call the API, then exchanges it again for an even more restricted token before passing control downstream.
  4. Each step produces a token scoped to exactly what that agent needs for that step, and nothing else.

The user’s identity propagates through the chain via the act claim in each exchanged token, so every API in the chain knows who the original user is and what they authorized. The audit trail is complete. No agent in the chain can exceed the permissions of the one above it.

{
...
"sub": "user-alice",
...
"act": {
"sub": "action-agent",
"iss": "https://idsvr.example.com",
"client_id": "action-agent",

"act": {
"sub": "summarization-agent",
"iss": "https://idsvr.example.com",
"client_id": "summarization-agent",

"act": {
"sub": "retrieval-agent",
"iss": "https://idsvr.example.com",
"client_id": "retrieval-agent",

"act": {
"sub": "orchestrator-agent",
"iss": "https://idsvr.example.com",
"client_id": "orchestrator-agent"
}
}
}
}
}

Most authorization servers support RFC 8693. The barrier to implementation is low, but the security improvement is significant.

Short-lived tokens, no refresh tokens, opaque for external agents

Beyond scopes and claims, a few implementation decisions significantly reduce your exposure:

No refresh tokens for agents

Agents should get time-limited access for the duration of their task. When they need a new token, they request one — giving the authorization server a new opportunity to re-evaluate scope and consent. Refresh tokens give agents standing access that persists beyond any single interaction, which is exactly the attack surface you don’t want.

Short expiry

Agent tokens should have lifetimes measured in minutes, not hours. The shorter the window, the smaller the blast radius if a token is compromised mid-chain.

Opaque tokens for external agents

For agents operating outside your trust boundary, never issue JWTs directly. JWTs are by-value tokens, decodable by anyone who holds them. If an external agent passes a JWT to an LLM or another agent, any claims in that token can leak. Issue opaque tokens instead. The agent gets a random string, and the API introspects it at validation time and gets the claims it needs. The token itself reveals no claims to anyone who intercepts it.

Human-in-the-loop for high-risk actions

Not every agent action should proceed automatically. When an agent requests a scope that exceeds a defined risk threshold: a financial transaction, deletion of user data, or modification of account settings, the authorization server should block token issuance and trigger an approval step.

Using Client-Initiated Backchannel Authentication (CIBA), this flow looks like:

  1. The agent requests a token with broad permissions from the authorization server.
  2. The server alerts the user directly via a push notification, SMS, or in-app prompt.
  3. The user reviews the specific action the agent is requesting and approves or denies it.
  4. The server issues a token valid for that specific action only, with a short expiry.

The agent waits throughout. Nothing proceeds until explicit approval is granted. The audit trail records the full chain: who instructed the agent, what it requested, who approved it, and what it was granted.

The baseline to aim for

Not a parallel security model for agents but a more precise application of the one you already have: restricted scopes, context-rich claims, audience-restricted tokens, short lifetimes, token exchange at every step, and human approval when the stakes are high.

For a deeper dive into the patterns covered here, see API Security Best Practices for AI Agents.

--

--

Curity
Curity

Written by Curity

Curity is the leading supplier of API-driven identity management, providing unified security for digital services. Visit curity.io or contact info@curity.io