6 min read

What happens when the agent calls a tool that calls an API?

Agents call tools, and tools call other services. Every hop needs a credential, and what gets handed along decides what the last service in the chain can know.

This lesson builds on the ones before it. If you arrived here first and a term is unfamiliar, lesson 1 is where they start, and each is in the glossary.

One more hop

So far the agent has called the calendar API directly. Often something sits in between. Alice asks the agent to find a time for a meeting. The agent calls a scheduling tool, which in MCP would be a server. The tool needs to see Alice’s calendar, so it calls the calendar API.

The agent has a token for the tool: Alice approved it, and its audience is the tool. Now the tool has to call the calendar API. What does it send?

There are three things it could reach for. Before you look, guess which of them lets the calendar API answer all three of its questions.

The tool sends the calendar API

The tool sends the calendar API: The token it was handed

Do not build this. The token was issued for the tool, not for the calendar API. Sending it on is called token passthrough, and MCP forbids it.

What arrives at the calendar API

{
  "sub": "alice",
  "client_id": "calendar-assistant",
  "aud": "https://scheduler.example",
  "scope": "meetings.schedule"
}
What the calendar API can tell
Is this for Alice?YesThe token names her.
Which software is calling?NoThe token names the agent’s app. The tool in the middle is invisible.
Was this issued for me?Noaud is the scheduling tool. The calendar API has to ignore the address to accept it.

This is the tempting one: the tool already holds a token, so why not use it? Because it only works if the calendar API stops checking who a token is for, and then any service that is ever handed a token from that issuer can use it there.

The tool sends the calendar API: Its own API key

What arrives at the calendar API

GET /events?day=tomorrow HTTP/1.1
Host: calendar.example
X-API-Key: sk_scheduler_41c0…
X-User: alice
What the calendar API can tell
Is this for Alice?Noalice is only the tool’s word. The key is the same for every user.
Which software is calling?PartlyThe tool, by its key. Not the agent behind it.
Was this issued for me?YesThe calendar API issued the key itself.

The first lesson again, one hop further along. The calendar API sees the tool and nobody else, so the tool needs access to everyone’s calendar, and the only thing keeping Alice’s request inside Alice’s calendar is the tool’s own code.

The tool sends the calendar API: A new token, made for this hop

What arrives at the calendar API

{
  "sub": "alice",
  "aud": "https://calendar.example",
  "scope": "calendar.read",
  "act": { "sub": "scheduling-tool" }
}
What the calendar API can tell
Is this for Alice?Yessub is still Alice.
Which software is calling?YesA second name has been added: act, the tool acting for her.
Was this issued for me?Yesaud is the calendar API.

The tool takes the token it was handed back to the authorization server and asks for a new one, for the next hop. The server decides whether this tool may act for Alice at the calendar API, and if so says exactly that in a fresh token. Each hop ends up holding a token that works in one place.

All three at a glance
The tool sends the calendar APIIs this for Alice?Which software is calling?Was this issued for me?
The token it was handedDo not build thisYesNoNo
Its own API keyNoPartlyYes
A new token, made for this hopYesYesYes

Why forwarding is the dangerous one

Forwarding feels harmless. It is the same user and the same request, and the token is right there. The harm is in what it requires of the calendar API: accepting a token that was addressed to someone else.

An API that does that can be used by any service holding any token from the same authorization server. A tool you connected for one purpose can quietly use your token for another. And an API that accepts tokens that were not addressed to it can be steered, by any caller holding one, into acting with authority that caller should not have. Security people call a service misused that way a confused deputy.

The audience check from the token lesson is the defense, and it only works if no service ever asks another to skip it.

What to do instead

The tool asks for a token of its own for the next hop. It takes the token it was handed back to the authorization server and asks for a new one, addressed to the calendar API. The authorization server decides whether this tool may act for Alice there, and if so issues it. That trade is a token exchange, and this is what then arrives at the calendar API:

{
  "sub": "alice",
  "aud": "https://calendar.example",
  "scope": "calendar.read",
  "act": { "sub": "scheduling-tool" }
}

Still about Alice, now addressed to the calendar API, and no wider than this step needs. So the rule is short: exchange, never forward.

Two ways to write “for Alice”

A token made for the next hop can be written two ways.

  • It can name only Alice. The calendar API then believes Alice is calling in person, and its logs will say so. This is impersonation.
  • It can name Alice, and separately the software acting for her. This is delegation, and the second name is called the actor. It is the act line in the token above.

Delegation is the one to want. The API can apply Alice’s permissions and the tool’s limits together, block one misbehaving tool without locking Alice out, and say afterward what did what. With impersonation the log shows Alice doing things at 3 a.m. that Alice never did.

One caution. Whether the new token carries an actor depends on the authorization server that issues it, and whether anything is done with it depends on the API. Check what your authorization server actually issues, and what your API actually reads, before you rely on it.

Where you will meet this

  • An MCP server that calls another API. It must not pass along the token the client sent it. It gets a token of its own for the API behind it, by exchange or by asking the user to connect that account directly.
  • An agent that hands work to another agent. The same question one level up: what does the second agent receive, and what can the service behind it tell?
  • A request that crosses into another company. Their authorization server does not know your users, so there are two trades: one at home for a short-lived grant, and one there for a token.
  • A request passed between services inside your own infrastructure. One variant makes a single exchange at the edge, for a short-lived token built to travel from service to service. What is never forwarded is a token addressed to someone else.

Check yourself

Answer before you read on. Nothing is recorded.

1A tool receives a token whose audience is the tool. To finish the job it has to call a billing API for the same user. What should it do?
  • Not quite. That token is addressed to the tool. The billing API should refuse it, and if it does not, any service holding a token can reuse it elsewhere.

  • Right. A new token for each hop: still about the user, addressed to the next API, and no wider than this step needs.

  • Not quite. Then the billing API cannot tell which user the request is for, and the tool can reach everyone’s data.

2The calendar API’s log says Alice deleted a meeting at 3 a.m. Alice was asleep. An agent did it. What kind of token produces a log like that?
  • Right. That is impersonation. The API cannot tell software from the person, so everything is recorded as hers.

  • Not quite. That is delegation, and the log would show both: Alice’s meeting, deleted by the tool acting for her.

  • Not quite. Then the log would show the tool and would not mention Alice at all.

3As a request passes down a chain of tools, what should happen to the access each one holds?
  • Not quite. Then the last service in the chain can do everything the first could, including things this request never needed.

  • Not quite. A tool that can ask for more than it was handed can be used to get around the limits on the one before it.

  • Right. One audience and a narrower scope at every exchange. Whatever goes wrong at one hop is then limited to that hop.

What to keep

  • A forwarded token only works if the next API stops checking the audience, and then any token from that issuer works there.
  • Delegation names the person and the software acting for them. Impersonation names only the person. Prefer delegation.
  • Access should shrink as it travels down a chain. It should never grow.

One rule

A service never passes on a token that was issued for itself. Exchange, never forward.

The names for these

The rest of this guide, and every specification, uses these terms. Each links to its entry in the glossary.

In this lessonIts nameDefined as
Forwarding the token you were handedToken passthroughForwarding a received token to another service instead of obtaining a new one for it. Prohibited by the MCP specification.
A service talked into misusing access it was lentConfused deputyA service with legitimate authority that is tricked into using it for a caller who should not have it. Agents that forward tokens or share one identity across users are prone to it.
Trading a token for a new one, for the next hopToken exchangePresenting one token to an authorization server to obtain another, typically for a different audience or with an actor added.
A token that names the person and the softwareDelegationActing for someone else in a way that keeps both identities visible: the token names the subject and, separately, the actor.
A token that names only the personImpersonationActing for someone else in a way that makes the software indistinguishable from the person: the token names only the subject.
The software named as actingActorThe party acting for a token’s subject, as the issuer names it in the act claim. Its presence is what distinguishes delegation from impersonation. It says who was authorized to act, not who is holding the token.
What some vendors call the exchangeOn-behalf-ofA general term, and some vendors’ product term, for a service obtaining a token to act for the user whose request it is handling.

Go deeper

The same ground at full depth, when you want it. None of it is needed for the next lesson.