Nobody disputes that the API gateway belongs at the center of an enterprise architecture. It is the discovery surface, the throttle, the routing layer, the audit point, and the place where a platform team decouples consumers from the services they consume. That is not the problem.
The problem starts the moment a gateway stops validating tokens and starts issuing them. At that point it is no longer a gateway. It is an identity provider. And in most estates I have looked at, it is not governed, audited, monitored, or operated as one. It is operated as middleware.
So let me put my position at the top rather than build to it. It is not the API gateway's job to be an identity provider. The gateway does discovery, governance, quota, decoupling, routing, and pre-authorization at the edge. It does not mint identity. Everything that follows is a reason why that line exists and an accounting of what it costs to cross it.
This article is a critical review of my own earlier piece, The industry does not have an agent identity propagation standard yet. In that article I drew a cross-provider agent flow, and I drew it clean, because I wanted the propagation problem to be legible. The simplification did its job. It also hid the thing I now think matters most: in a real enterprise topology, the gateway quietly becomes an extra authorization server, and nobody counts it.
Let me be honest about what this is. It is not a migration plan. It is a view, and an attempt to raise awareness of a risk that gets dismissed in design reviews with a shrug and the phrase "that is just how our platform works." I know these are brownfield estates. I know a re-platform does not land in a quarter, or in a year. I also know that most of the decisions that produced this shape were rational at the time they were made, taken by competent people under real constraints. None of that changes what the resulting architecture is. It is a liability, it deserves to be named as one, and naming it is not where the work stops.
So here is the recommendation the rest of this article argues for, stated before the argument. Start consolidating your identity providers now, and keep driving the count down until the gateway is not one of them. That is not a personal preference. Microsoft's CISA Zero Trust Maturity Model guidance for the identity pillar recommends consolidation of identity providers, identity stores, and identity management systems as the way to establish an identity foundation at all, and the enterprise-wide identity management guidance for M-22-09 puts the target plainly: as few managed identity systems as possible, with a consolidation plan behind them. Slow is acceptable. Not started is not.
The words I use are OAuth words
Before the argument, the vocabulary. I am not inventing terms here, and I want the disagreement to be about architecture rather than about definitions.
RFC 6749 section 1.1 defines four roles, and every one of them shows up in this article. The resource owner is the entity capable of granting access to a protected resource, which in this article is Bob. The resource server hosts the protected resource and accepts access tokens. The client is the application making requests on the resource owner's behalf. The authorization server issues tokens after authenticating the resource owner and obtaining authorization. OpenID Connect Core 1.0 sits on top of that as the identity layer, which is how a client learns who Bob actually is rather than merely that some authorization exists.
Four claims carry the whole argument.
sub is the subject, the entity the token is about. RFC 7519 section 4.1.2 defines it as the principal that is the subject of the JWT, and states plainly that the value is only guaranteed to be unique within the issuer's scope. Hold on to that sentence. It becomes the crux of this article.
client_id identifies the client the token was issued to. RFC 8693 section 4.3 defines it as the client identifier of the party to whom the token was issued, and RFC 9068 section 2.2 makes it a required claim in a standards-compliant JWT access token. Microsoft Entra spells the same idea as appid in v1.0 tokens and azp in v2.0 tokens, which the access token claims reference documents alongside the rest of the claim set.
act is the actor. RFC 8693 section 4.1 defines it as the party acting on behalf of the subject, and it nests, so a chain of delegation can be expressed as a chain of act claims.
The rule that follows from those definitions is small, and it is the one people skip. sub answers who authorized this, and the client and actor claims answer who is carrying that authorization. Those are two different questions with two different answers, and an architecture that collapses them into one has stopped being able to answer either.
The gateway's job is governance, not authorization
Start with the version of the world where everything is tidy.
The estate is deliberately small. There is an AI agent. There are two remote MCP servers, A and B. There is a REST API that the agent calls directly through a local tool. There is a single-page application that Bob uses. There is Bob. Behind the MCP servers there are the systems they actually talk to, another REST API and a database. I have left the LLM out of the picture entirely, because the model is not an identity, and the REST API stands in well enough for "a thing the agent calls that has its own access control."
One assumption holds this picture together, and I want it stated rather than implied. In this version, the gateway is not an authorization server. Every resource in the estate is registered with the same identity provider. The gateway sits in the traffic path and does gateway things.
What are gateway things? Discovery, so consumers can find an API without asking a human. Governance, so the platform team can see what is being called and by whom. Quotas and rate limiting, so one badly written client does not take down a shared dependency. Decoupling, so a backend can move without breaking every caller. Routing, transformation, and versioning. The Azure API Management authentication and authorization overview describes exactly this shape of responsibility, and it is a good shape.
Pre-authorization at the edge belongs in that list too. A gateway that checks whether an inbound token is well formed, unexpired, signed by a trusted issuer, and carrying the audience it should be carrying is doing valuable work. The validate-jwt policy is precisely the right shape of control, a cheap early sanity check that rejects obvious garbage before it reaches a backend. I have no argument with any of that.
Here is where I draw the line. It is not the gateway's job to decide whether the SPA may invoke the agent. It is not the gateway's job to decide whether the agent may invoke MCP Server A rather than MCP Server B. Those are authorization decisions about business capability, and they belong to an authorization server that owns the identities and the entitlements involved. A gateway that pre-authorizes is enforcing a decision. A gateway that authorizes is making one, and those are not the same architectural role.
A gateway that issues its own tokens has gone past both. It is not enforcing a decision and it is not making one. It is manufacturing the subject that every downstream decision will be made about. That is the identity provider's job, it is the only job on this page the gateway should not have, and no amount of policy configuration turns it into a gateway concern.
A plausible execution path
Now run a request through it, and count the hops honestly.
Bob signs in to the SPA (1). During that sign-in he also authorizes the SPA to invoke the AI agent on his behalf. He is the resource owner, the SPA is the client, and the agent is a resource he is delegating access to.
Bob types a prompt. The SPA invokes the agent (2), carrying Bob's delegated authorization.
The agent validates the request and builds a plan. The plan has three branches. It calls a local tool that hits a REST API (3). It calls MCP Server A (4), and MCP Server A must in turn call a downstream REST API (5) to do its work. It calls MCP Server B (6), and MCP Server B must run a query against a database (7).
Because the agent is acting on Bob's behalf and not on its own account, Bob's identity has to survive every one of those hops. That is not a nice-to-have. If the downstream REST API at step 5 cannot tell that Bob is the reason it is being called, it cannot apply Bob's entitlements, and the agent has just become a confused deputy with a wider reach than any human user. So Bob must hold entitlements in the agent, in the REST API at step 3, in MCP Server A, in the REST API at step 5, in MCP Server B, and in the database at step 7.
The MCP hops are not a matter of preference. The MCP authorization specification treats MCP servers as OAuth 2.1 resource servers and states that a server MUST NOT pass through the token it received to an upstream service. Each hop is a fresh authorization decision by design, and the spec is right to require it. Token pass-through destroys audience binding and turns every server in the chain into an amplifier for whatever token happens to arrive.
I want to be clear that this is not a contrived example built to make a point. It is the ordinary shape of agentic work. An agent that cannot call more than one tool, or whose tools never call anything themselves, is a demo. Anything doing real work in an enterprise looks like this or worse, and "worse" usually means more hops, more providers, and more places where the chain is only as strong as the weakest assertion in it.
In the ideal world, one authorization server sees all seven token requests
Suppose the estate is greenfield and someone with authority made the obvious call: everything registers with one authorization server. Bob exists there as a user. The SPA is registered there as a client. The agent has its own identity there, distinct from Bob's. The REST APIs, both MCP servers, and the database all register there as resource servers with their own scopes.
Seven token requests, and every one of them is an entitlement question with an answer.
- The SPA authenticates Bob. Bob needs an entitlement to use the SPA at all.
- The SPA obtains delegated authorization to invoke the agent. Bob needs an entitlement to the agent, and the SPA needs to be authorized to ask for it on his behalf.
- The agent obtains a token for the REST API. Bob needs an entitlement in that API, and the agent needs to be permitted to request it.
- The agent obtains a delegated token for MCP Server A.
- MCP Server A obtains a token for the downstream REST API on Bob's behalf. Both MCP Server A and Bob need entitlements there, and they are separate checks.
- The agent obtains a delegated token for MCP Server B.
- MCP Server B obtains a token for the database on Bob's behalf, with the same double check.
This pattern has a name, and the standards already carry language for it. RFC 8693 section 1.1 distinguishes delegation, where the acting party is given permission to act on the subject's behalf and both parties stay visible in the token, from impersonation, where the acting party disappears and the resource server cannot tell the difference. Microsoft's on-behalf-of flow is the same idea with a vendor implementation attached.
Now count how many times Bob appears as sub in that chain. Seven times, issued by one issuer, with one meaning. There is one policy engine, one place where entitlements live, one enforcement surface, and therefore exactly one place where the entire chain can be denied. Revoke Bob at the authorization server and every hop downstream loses its footing on the next token request. Investigate an incident and there is one issuance log to correlate against.
One authorization server, all resources registered with it, one policy engine. Almost nobody reading this is standing there today, and I am not pretending otherwise. It remains the direction every estate should be actively moving in, and the distance from it is a number you should be able to say out loud: how many authorization servers issue tokens your systems will accept, and which of them has an owner and a retirement date. Microsoft's guidance on migrating apps and authentication to Microsoft Entra ID exists because that consolidation is a program of work rather than a configuration change. Programs of work have to be started before they can finish.
The real world runs four authorization servers, not three
The first reality is that you do not have one identity provider. You have several, with users in some of them, resources in others, and a partial overlap that nobody has fully mapped. And I do not mean the tidy split people reach for first, the on-premises directory alongside the cloud directory with a sync between them. That one at least has a documented relationship and an owner. I mean the genuine fragmentation: an acquired business unit with its own tenant, a SaaS platform with its own embedded authorization server, a legacy estate fronted by a federation product that predates everyone currently on the team, and a partner integration that authenticates against something nobody has permission to change.
Every one of those has a story attached, and most of the stories are true. None of them makes the shape permanent. The number of identity providers in an estate is a design choice that got made incrementally, one acquisition and one integration at a time, and it comes back down the same way. Treat that number as a metric with an owner, not as weather.
The second reality is what teams did about it. To hide that fragmentation from application developers, they made the gateway an authorization server. Not as an act of vandalism, and not against the documentation either. Fronting a backend with the gateway as the token audience is a supported, documented pattern, and the APIM authentication and authorization overview covers scenarios in exactly that family. It works. It ships. It removes a class of problem from every application team at once, which is why it wins the design review.
Walk the same flow through that topology.
Step 1. Bob signs in to the SPA against IDP 0. So far, unchanged.
Step 2. The agent is not directly reachable. It sits behind the gateway. So the resource server registered in IDP 0 is not the agent, it is the gateway. The SPA requests a token to invoke "something in the gateway," and IDP 0 has no opinion about which something, because the gateway is a single registered audience covering many backends.
Step 2.1. This is the step that does not appear in anybody's architecture diagram, and it is the reason I am writing this. The gateway validates the incoming token from IDP 0, runs its own policy, and then issues its own token from its own security token service. From here inward, the estate no longer runs on IDP 0 tokens. It runs on gateway tokens.
Step 3 is skipped here on purpose. I am keeping the numbering aligned with the ideal-world walkthrough so the two can be compared line by line, and the direct REST API call adds nothing that the MCP branches do not already show.
Step 4. The agent is now free of external authorization servers, which was the entire selling point. It validates a gateway STS token and calls MCP Server A through the gateway. Clean, simple, and completely dependent on the gateway being right.
Step 5. MCP Server A has to call a REST API that does not trust IDP 0 or the gateway. It trusts IDP 1. So MCP Server A registers as a client in IDP 1 and requests a token there. And that request has to assert three things at once: that Bob exists in IDP 1, that this Bob is the same Bob who signed in to IDP 0 at step 1, and that he holds entitlements in that REST API. Three assertions, and only the third is a normal authorization check.
Steps 6 and 7. The same again, with MCP Server B, IDP 2, and the database behind it. Another registration, another mapping, another set of three assertions.
Count the authorization servers in that picture. IDP 0, IDP 1, IDP 2, and the gateway's own STS. Four. Ask an architect how many identity providers are in the flow and you will usually be told three, because the fourth one is drawn as a rectangle with a networking icon on it.
There are two places inside the gateway where Bob changes identity
This is the part I want people to sit with.
At step 2.1, Bob's authorization from IDP 0 becomes "Bob's" authorization from the gateway STS. At step 5, that gateway assertion becomes the basis for asserting Bob in IDP 1. Two translations, neither of them visible in the request path, neither of them producing an artifact that an auditor would recognize as an identity event.
flowchart LR
Bob["Bob<br/>IDP 0"]
SPA["SPA"]
GW["API<br/>gateway"]
Agent["Agent"]
MCPA["MCP<br/>Server A"]
API["REST API<br/>trusts IDP 1"]
Bob -->|"1. sign-in<br/>delegates<br/>to SPA"| SPA
SPA -->|"2. token<br/>iss: IDP 0<br/>aud: gateway"| GW
GW -->|"TRANSLATION 1<br/>step 2.1<br/>gateway STS<br/>mints Bob"| Agent
Agent -->|"4. routed<br/>via gateway"| MCPA
MCPA -->|"TRANSLATION 2<br/>step 5<br/>asserts Bob<br/>into IDP 1"| API
linkStyle 2 stroke:#d62728,stroke-width:3px
linkStyle 4 stroke:#d62728,stroke-width:3px
Remember what RFC 7519 section 4.1.2 actually says about sub. The value is unique within the issuer's scope. Not globally. Not across your estate. Within the issuer. So when the gateway STS emits a token whose sub reads like Bob, that value means whatever the gateway says it means, and when MCP Server A turns that into an IDP 1 assertion, the identity has been through two mappings that no standard is validating for you.
The consequence is one sentence long. Whoever controls the gateway decides who Bob is.
Two questions follow, and in every estate where I have asked them, neither has had a satisfying answer. First, how do you trace that the Bob who signed in at step 1 is the Bob whose entitlements were used at step 5? The correlation exists, if it exists at all, in gateway policy configuration and gateway logs, which are owned by a different team than the one that owns the identity logs. Second, if Bob at step 1 is compromised, what locks down Bob at step 5? Disabling the account in IDP 0 stops new sign-ins. It does not tell the gateway STS to stop minting, and it does not tell IDP 1 anything at all, because IDP 1 was never told that its Bob and IDP 0's Bob were related.
Compare that with what the standards are actually asking for. RFC 8707 resource indicators exists so a client can name the resource it wants a token for, and so the authorization server can bind the token to that audience. The MCP security best practices require a server to reject any token that was not issued for it, and name the confused deputy problem explicitly. Both controls point the same direction: narrow the audience, keep the issuer meaningful, refuse tokens minted for somebody else. A gateway that re-mints identity at the edge is doing the opposite of audience binding. It is deliberately widening the audience so that everything behind it can stop caring.
So here is the position, and I hold it without qualification. In trying to make things simpler behind the gateway, the industry made them worse, because it pushed the gateway into acting as an identity provider without ever admitting that is what happened. The simplicity is real. It was purchased with a trust anchor, and the invoice has not been read. A gateway that mints identity is not a pragmatic shortcut with a documentation page behind it. It is an unowned authorization server sitting in the middle of your estate, and it should not be there.
Four policy engines is a liability, and it should be called one
I will concede the same ground twice, because it is fair ground. These are brownfield systems. They carry years of integrations, contracts, and behavior that nobody has fully documented. The gateway STS does not come out next sprint, and I am not asking anyone to pretend otherwise.
The concession explains why this is hard. It does not excuse leaving it alone. Two things have to happen, and they run in parallel rather than in sequence. The first is naming the liability, because the first control you apply to a liability is writing its real name into a register that somebody reviews. The second is reducing the number of authorization servers in the estate on a schedule that has an owner, starting with the one that was never classified as an authorization server in the first place.
Four authorization servers means four policy engines. Four places where entitlements are managed, with four different models for expressing them. Four places where human and non-human identities are provisioned and deprovisioned, with four different joiner, mover, leaver processes, one of which is a configuration file. Four places where a broad and fragile trust relationship gets created, and only three of them will show up in an identity governance review.
The ownership asymmetry is the part that should worry you most. The gateway belongs to the application platform team. It does not belong to security, and it very rarely belongs to IAM. So the controls that IDP 0, IDP 1, and IDP 2 are subject to, privileged access review, signing key custody and rotation, conditional access on administrative operations, change approval on trust configuration, alerting on issuance policy changes, are simply not applied to the fourth authorization server. Not because anyone decided to exempt it. Because nobody classified it as one.
Now look at it the way an adversary does. IDP 1 gets you the users and resources in IDP 1. The gateway STS gets you an assertion that IDP 1 will accept, an assertion that IDP 2 will accept, and an assertion that every service behind the gateway will accept without further question. To an attacker, that gateway is worth more than IDP 1. It is also patched on an application team's schedule, monitored with application telemetry, and administered by people whose access was never reviewed as identity provider access, because on the asset inventory it is middleware.
RFC 8693 does not fix a broken trust anchor
Whenever I make this argument, somebody reaches for token exchange, so let me address it directly rather than leave it sitting as an unstated rebuttal.
RFC 8693 is a good specification and I am not arguing against using it. It gives you a real protocol for a security token service: a subject_token describing the party on whose behalf the request is made, an optional actor_token describing the party doing the acting, and a token type system that lets you convert between formats deliberately instead of by convention. It gives you the act claim as a nested, inspectable delegation history, so a resource server can see the whole chain rather than a flattened identity. It even gives you may_act, a claim stating which party is authorized to become the actor for a subject, which is genuinely the right primitive for constraining delegation.
Here is what it does not give you: a reason to believe the mapping. RFC 8693 supplies mechanics for exchanging one token for another. It explicitly places the trust model and the policy governing exchanges outside its scope, and it imposes no requirements on how a deployment decides that this subject in this issuer corresponds to that subject in that issuer. That decision is yours. In the architecture above, the answer to "why should IDP 1 believe this is Bob" is that somebody configured a mapping in the gateway's STS, carefully, once, some time ago, and it has been correct ever since as far as anyone knows.
The specification is candid about where that leads. It warns that when an authorization server does not authenticate the client in a token exchange, a compromised or leaked token can be leveraged through the STS into other tokens, and it tells you to require client authentication and to constrain who may exchange what. Apply that warning to a gateway STS that fronts an entire estate and the exposure takes an obvious shape. Control the gateway STS, or control anything that can persuade it to mint, and you can obtain a token for any user in any provider that trusts it. Not through a vulnerability. Through the feature.
So the closing rule is the one I would defend in any design review. Token exchange is a mechanism for propagating identity. It is not a mechanism for establishing who is allowed to assert it. The propagation problem is largely solved, and the standards are in decent shape. The assertion problem is the one your architecture answered by accident.
Which brings me back to where I started, and I will state it once more without softening it. It is not the API gateway's job to be an identity provider. Discovery, governance, quotas, decoupling, routing, versioning, and pre-authorization at the edge are the gateway's work, and a good gateway is genuinely excellent at all of it. Minting the subject that the rest of the estate authorizes against was never on that list and should not have been added to it.
Two actions follow, and they are not alternatives to each other.
Start the first one this quarter. If the gateway is asserting identity today, govern it as an identity provider, because the only other option available right now is an ungoverned one. Put it in the identity asset inventory. Review its administrators as privileged identity administrators. Rotate and custody its signing keys the way you custody an identity provider's. Put change approval on its trust configuration and alerting on its issuance policy. Feed its issuance logs into the same correlation surface as every other issuer, so a chain from step 1 to step 5 can actually be reconstructed.
Then fund the second one. Count the authorization servers your estate trusts, put a name and a date against each one you intend to retire, and drive that number down until the gateway is out of the identity business entirely and back to being the very good gateway it already is. That work is slow, it is unglamorous, and it will outlast several reorganizations. Start it anyway, because the count does not fall on its own.
And hold the line on new build while you do it. Nothing greenfield gets to add another authorization server, and nothing new gets fronted by a gateway that mints its own tokens. If you will not govern the gateway as an identity provider, do not let it assert identity.
References
- The industry does not have an agent identity propagation standard yet
- RFC 6749 section 1.1, OAuth 2.0 roles
- OpenID Connect Core 1.0
- RFC 7519 section 4.1.2, the sub claim
- RFC 8693, OAuth 2.0 Token Exchange
- RFC 8693 section 1.1, delegation and impersonation
- RFC 8693 section 4.1, the act claim
- RFC 8693 section 4.3, the client_id claim
- RFC 8693 section 4.4, the may_act claim
- RFC 9068 section 2.2, required claims in JWT access tokens
- RFC 8707, Resource Indicators for OAuth 2.0
- Microsoft Entra access token claims reference
- Microsoft identity platform on-behalf-of flow
- CISA Zero Trust Maturity Model for the identity pillar
- Memo 22-09 enterprise-wide identity management system
- Migrate application authentication to Microsoft Entra ID
- Azure API Management authentication and authorization overview


Top comments (1)
The line that lands for me: the gateway becomes an extra authorization server and nobody counts it. I've watched the same movie from the opposite end - I run a public board where agents post with deliberately zero identity: no signup, no tokens, no keys. Even there the attacks are not about stealing identity, they're about borrowing authority (spam written at agents, asking them to relay and index content into their own memory). Minting identity you don't govern and propagating instructions you didn't write are the same shape: someone speaking with authority they didn't earn. Naming the audit gap is the part design reviews keep skipping.