
ENTERPRISE
An employee-authorized agent accumulates OAuth grants across a dozen SaaS tenants, each surviving offboarding alone. The federation standards that make that governable are arriving now.
TL;DR
Agent SaaS sprawl isn't a discipline problem. It's an architecture problem, and the fix is moving the authorization decision to the identity provider a company already runs.
Eight hundred employees clicking "allow" on eight hundred separate OAuth consent screens produce thousands of refresh tokens that outlive employment, survive independently of each other, and answer to no single system. Okta's Cross-App Access ecosystem already lists more than two dozen partners spanning identity providers, agent vendors, and the SaaS applications they connect to.
Telling employees to be more careful doesn't touch this. The problem isn't carelessness. It's that no system holds the union of what's been granted, so there's nothing to be careful with.
We're not saying this is solved. Coverage is partial, the core specification is still a working-group draft, and an application that hasn't implemented it keeps handing out tokens exactly as it does today.
What's changed is that three IETF and OpenID specifications went from draft to genuinely usable in the last year. A company running its own IdP can start requiring brokered access from the vendors that support it, and push the rest.
Take an employee at a four-thousand-person company who installs an AI assistant and connects it to Slack, then Google Drive because meeting prep needs the documents, then Jira because the sprint board is context, then Salesforce, Confluence, Zoom, Figma, Datadog. Each connection is an ordinary OAuth authorization-code flow. Each is legitimate: a real user consenting to real scopes on their own data. Each also produces a refresh token held by a vendor the company has no contract with, and that token survives independently of every other grant the employee has made.
Multiply by eight hundred employees doing some version of the same thing. What comes out the other side is an access topology no one has ever seen in full: several thousand credentials the company did not issue, cannot enumerate, and cannot revoke centrally. When that employee leaves, IT disables their identity-provider account. The refresh token the assistant vendor is still holding for Salesforce doesn't notice.
Credential hygiene and agent offboarding get covered as practices elsewhere on this site. This post is about the layer underneath them: four federation standards, at wildly different stages of readiness, that change who is actually in the loop when an agent gets access to company SaaS in the first place.
The IETF's Identity Assertion JWT Authorization Grant (the industry mostly just calls it Cross-App Access) is a working-group document at revision 04. The OpenID Foundation's Shared Signals Framework and CAEP reached Final Specification status in September 2025. IPSIE is profiling the whole enterprise identity stack, agents included. And SCIM extensions for agents exist as two competing individual drafts, neither adopted by a working group yet. Getting precise about which of those four is real infrastructure and which is still a good idea on paper is most of what this post is for.
The governing insight: every individual OAuth grant is small and reasonable on its own. Sprawl is what piles up when nobody owns the aggregate. Move the decision to the one system that already has enterprise context, and there's finally something to own.
We want to state the mechanics precisely, because this isn't a carelessness problem and it can't be trained away.
In the app-to-app model, the assistant is an OAuth client to each SaaS tenant independently. The employee is redirected to Salesforce, authenticates (often through the company's own IdP, which is the cruel part: SSO is involved and still learns nothing about what's being authorized), consents to a scope set, and the assistant receives tokens. From the IdP's perspective, a user logged into Salesforce. That's all it saw.
Three properties follow, and each is bad on its own.
Invisibility. No system holds the union of these grants. Salesforce knows about its own; Slack knows about its own. Enumerating the set means an administrator visiting every SaaS admin console, finding the connected-apps page, and reading it, assuming that page exists, exposes third-party grants, and is exportable. Plenty don't.
Independent survival. Each grant's lifecycle is anchored to the SaaS tenant rather than to employment. Disabling the IdP account stops new interactive logins. It doesn't touch a refresh token already sitting in a vendor's database, because the refresh grant never consults the IdP in the first place.
Consent granularity mismatch, and drift. The consent screen offers whatever scopes the vendor defined, and the employee accepts them to make the tool work. Whether a marketing coordinator should be able to grant an external agent write access to the CRM is a company policy question, and it gets answered, implicitly and permanently, by the marketing coordinator. And when the vendor adds a feature and requests more scopes at the next connection, exposure grows on the vendor's release schedule, not the company's.
We don't count the usual responses to this as controls. An annual review of eight hundred SaaS admin consoles doesn't touch something that changes weekly. A consent screen an employee clicks through to get a tool working is a liability release, not governance.
Consider a meeting-prep agent that reads calendars, pulls the relevant documents, checks recent Slack threads with attendees, and summarizes open Jira tickets. That's four grants for one useful feature, held by one vendor, on behalf of one employee. It's a good product. It's also, at scale, several thousand credentials a security team cannot see.
Slack | Drive | Jira | CRM each grant --> agent vendor holds N independent refresh tokens IdP .... sees logins only, no grant visibility, no revocation reach
IDP-BROKERED Employee --SSO once--> IdP [policy + audit + one revocation point] IdP --brokered grant per app, per policy--> Slack AS | Drive AS Jira AS | CRM AS -->
Figure 1 — The same access, granted two ways. The difference is whether the IdP is a bystander or the broker.
The naive version of "route it through the IdP" would have the IdP issue access tokens for every SaaS API directly. That fails for an instructive reason: it would require every vendor to accept a foreign issuer's tokens for its own resources, abandoning control over its authorization decisions, scope definitions, rate limits, and token formats. No serious vendor will do that, and they shouldn't.
The design that works splits the decision. The IdP decides whether this client may act for this user against this application at all, a question it's positioned to answer because it already knows the employee, the group memberships, the device posture, and the policy in force. The resource application's authorization server decides what access to actually grant and issues its own token, because it owns the scopes and the data.
The Identity Assertion JWT Authorization Grant draft states this explicitly. Unlike profiles in which the IdP issues access tokens consumed directly by the resource server, it "preserves the Resource Authorization Server as the issuer of access tokens for its protected resources. This lets the IdP centralize federated identity, SSO trust, and the decision to broker cross-app access, while the Resource Authorization Server keeps independent control over its own access tokens."
The precondition is a trust triangle that mostly already exists. The client must have a relying-party relationship with the IdP for SSO, and the resource authorization server must independently trust that same IdP for SSO and subject resolution. Both are true in any company where the wiki and the chat app sit behind the corporate IdP, which is to say most companies. Cross-App Access extends that existing trust from authentication to API authorization, rather than asking anyone to establish something new. One consequence is where the user-experience win comes from: the resource authorization server doesn't need to obtain user consent again at the exchange step, because the IdP's administrative policy stands in for the per-app consent click. That's the whole point, and it's also why we'd want that policy to be right before anyone flips it on.
The specification is draft-ietf-oauth-identity-assertion-authz-grant, at revision 04, published 21 May 2026,
authored by Aaron Parecki of Okta, Karl McGuinness, and Brian Campbell of Ping Identity. It's a work item of
the IETF's Web Authorization Protocol working group, with an intended status of Proposed Standard. It profiles
the more general draft-ietf-oauth-identity-chaining ("OAuth Identity and Authorization Chaining Across
Domains," revision 17 as of 19 July 2026), which leaves most of cross-domain token chaining unspecified.
Cross-App Access is the part that gets pinned down enough to actually interoperate.
There are three steps. Step one is ordinary SSO. The employee signs in to the client through the corporate IdP, and the client receives an identity assertion (an OpenID Connect ID token or a SAML 2.0 assertion) plus, optionally, a refresh token.
Step two is a token exchange at the IdP, which returns not an access token but an intermediate artifact: the Identity Assertion JWT Authorization Grant, or ID-JAG.
POST /oauth2/token HTTP/1.1
Host: acme.idp.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
&audience=https://acme.chat.example/
&resource=https://api.chat.example/
&scope=chat.read+chat.history
&subject_token=eyJraWQiOiJzMTZ0cVNtODhwREo4VGZCXzdrSEtQ...
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=eyJhbGciOiJSUzI1NiIsImtpZCI6IjIyIn0...audience is REQUIRED and identifies the resource authorization server. Implementations MUST accept identity
assertions as the subject_token; they MAY additionally accept a previously issued refresh token, letting a
client obtain a fresh ID-JAG without dragging the user through SSO again. This is the request the IdP evaluates
against administrator-defined policy, which is the moment enterprise governance actually happens.
The ID-JAG that comes back is a JWT with typ of oauth-id-jag+jwt, carrying iss, sub, aud, client_id,
jti, exp and iat as required claims, plus optional resource, scope, authorization_details for Rich
Authorization Requests, tenant, auth_time, acr, amr and act. Its lifetime is short (the MCP profile's
example uses 300 seconds) because it carries a policy decision, not a credential meant for ongoing work.
{
"typ": "oauth-id-jag+jwt",
"alg": "RS256"
}
{
"jti": "9e43f81b64a33f20116179",
"iss": "https://acme.idp.example",
"sub": "U019488227",
"email": "user@example.com",
"aud": "https://auth.chat.example/",
"resource": "https://mcp.chat.example/",
"client_id": "f53f191f9311af35",
"exp": 1311281970,
"iat": 1311280970,
"scope": "chat.read chat.history"
}Step three redeems the ID-JAG at the resource authorization server as an RFC 7523 JWT bearer assertion:
POST /oauth2/token HTTP/1.1
Host: auth.chat.example
Content-Type: application/x-www-form-urlencoded
grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion=eyJhbGciOiJIUzI1NiIsI...
&client_id=https://client.example.com/client.jsonThe resource authorization server validates the typ, the audience and the signature against the IdP it
trusts, resolves the subject to a local account (with just-in-time provisioning if policy allows), applies its
own policy, and issues its own access token. Clients discover support by looking for
urn:ietf:params:oauth:grant-profile:id-jag in the authorization_grant_profiles_supported field of the
resource authorization server's metadata.
MCP has adopted this directly. The Enterprise-Managed Authorization extension in the
modelcontextprotocol/ext-auth repository is marked Stable, and is explicitly "an application of the
Identity Assertion JWT Authorization Grant for use within enterprise deployments of the Model Context
Protocol." In that profile the MCP client is the client, the MCP server is the resource server, and the
resource authorization server is whatever the MCP server advertises in its RFC 9728 protected resource
metadata. The extension adds one requirement worth flagging: the issued access token MUST be
audience-restricted to the MCP server identified by the resource claim in the ID-JAG.
Enterprise IdP ==ID Token==> Agent Client Client --token-exchange (requested_token_type=id-jag, audience=Resource AS)--> IdP IdP evaluates admin policy ==ID-JAG (short-lived, signed)==> Client Client --jwt-bearer grant, assertion=ID-JAG--> Resource AS Resource AS validates + resolves subject + local policy ==access token, aud = this API only==> Client Client --API call--> SaaS API -->
Figure 2 — Cross-App Access. The IdP decides whether; the resource authorization server decides what.
Cross-App Access solves one problem. Enterprise identity has six or seven, the specifications for each already exist, and none of them agree on how they fit together. That's the gap IPSIE addresses.
The OpenID Foundation chartered the IPSIE working group in October 2024. The working group's name is Interoperability Profiling for Secure Identity in the Enterprise; its deliverable is the Interoperability Profile for Secure Identity in the Enterprise. Its method isn't to invent protocols but to profile existing ones (the working group names OpenID Connect, Shared Signals, OAuth 2.0, SCIM, "and more") into a single document with sections per use case.
The problem space IPSIE opens with is the useful part to read, because it fairly enumerates what enterprises can't currently do interoperably: single sign-on, lifecycle management, entitlements, risk signal sharing, logout, and token revocation. Every one of those has a specification. Almost none has a profile precise enough that two vendors implementing independently will interoperate on the first try, which is why enterprise identity integration is still measured in weeks per application. An agent getting access through an IdP inherits whatever the IdP can express and propagate, so IPSIE's relevance here is direct: it's the work of making that interoperable.
We'd rather state IPSIE's maturity plainly than dress it up. The specifications page lists a v1 draft, and records "None yet" for both Final Specifications and Implementer's Drafts. This is profile-stage work. Directionally right, and not something to write into a procurement contract this quarter.
The most valuable operational property of brokered access is that revocation finally has somewhere to originate. But origination isn't propagation, and unusually for this space, the standards for propagation are actually finished.
On 2 September 2025 the OpenID Foundation membership approved three Shared Signals specifications as Final: the OpenID Shared Signals Framework 1.0, OpenID CAEP 1.0, and OpenID RISC 1.0. A Final Specification carries intellectual-property protections for implementers and isn't subject to further revision, which is a materially different procurement posture than a draft.
The Shared Signals Framework is the transport: transmitters and receivers exchanging Security Event Tokens over a defined stream-management API. CAEP, the Continuous Access Evaluation Profile published 29 August 2025 by Tim Cappalli of Okta and Atul Tulshibagwale of SGNL, defines what the events mean. Its framing anticipates the agent case in passing: transmitters send continuous updates receivers use to "attenuate access to shared human or robotic users, devices, sessions and applications."
CAEP defines eight event types, all under https://schemas.openid.net/secevent/caep/event-type/:
| Event type | Signals |
|---|---|
session-revoked | A session has been revoked; receivers should terminate applicable sessions |
session-established / session-presented | A session was created, or an active one was observed at the transmitter |
token-claims-change | Claims within a token have changed |
credential-change | A credential was created, updated, revoked, or deleted |
assurance-level-change | Authentication strength changed, against a named framework |
device-compliance-change | A device moved between compliant and non-compliant |
risk-level-change | The assessed risk level for a subject changed |
A session-revoked event is an ordinary Security Event Token:
{
"iss": "https://idp.example.com/123456789/",
"jti": "24c63fb56e5a2d77a6b512616ca9fa24",
"iat": 1615305159,
"aud": "https://sp.example.com/caep",
"txn": "8675309",
"sub_id": {
"format": "opaque",
"id": "dMTlD|1600802906337.16|16008.16"
},
"events": {
"https://schemas.openid.net/secevent/caep/event-type/session-revoked": {
"event_timestamp": 1615304991
}
}
}Put this together with brokered access and offboarding stops being an archaeology exercise. The employee is
disabled at the IdP, which transmits session-revoked (and, where appropriate, credential-change) to every
subscribed receiver. Receivers terminate sessions and invalidate the access tokens they issued off the back of
an ID-JAG. No new ID-JAG can be minted for a disabled subject, so nothing renews. The chain closes from both
ends: nothing new gets granted, and what already exists gets torn down.
Figure 3 — A Shared Signals revocation event propagating. Brokering closes the front door; CAEP closes the back one.
Everything above governs an agent acting for a user. It says nothing about the agent as a thing that exists, has an owner, and should eventually be decommissioned. That's a provisioning problem, and provisioning has a standard: SCIM, defined by RFC 7643 for the core schema and RFC 7644 for the protocol.
SCIM's object model has User and Group, and neither fits an agent well. An agent is not a person and not a
group, and modelling it as a service account throws away exactly the attributes that matter: who owns it, what
protocols it speaks, which application hosts it, whether it has a parent agent.
Two individual IETF submissions are attempting this, and their state is the honest headline. "SCIM Agents and
Agentic Applications Extension" (draft-abbey-scim-agent-extension-00, 16 October 2025, by M. Abbey and R.
S. Cohen of Okta) defines two resource types, Agent and AgenticApplication. The agent carries active as
administrative status, agentType for classification, x509Certificates and subject for token federation,
entitlements, roles and groups for access, owners referencing Users or Groups as accountable parties,
parent for hierarchy, and a protocols attribute describing the interfaces it speaks, with types including
A2A, OpenAPI and MCP-Server. That draft expired on 19 April 2026 and hasn't been revised.
"AI Agent Resource Extension for SCIM" (draft-wzdk-scim-agent-resource-00, 5 June 2026) takes a second
run at the same ground, and its author list is the interesting part: Mark Wahl and Pamela Dingle of Microsoft,
Danny Zollner of Okta, and Ismael Kazzouzi of Nextident. A cross-vendor draft from two of the largest enterprise
identity vendors is a meaningful signal about where this lands. It's also still a revision-00 individual
submission that no working group has adopted.
We think the reason to care despite that immaturity is that owners is the field the entire governance story
depends on. An agent whose record names an accountable human appears in that human's access review, gets
flagged when they leave, and has someone to ask about. An agent with no owner is a permanent orphan, and the
industry already has enough of those.
Set the specifications aside and consider what a security team can actually do differently.
We'd treat one honest limitation as a design boundary rather than a gap to apologize for, because the MCP extension states it plainly: the visibility the IdP gains "is limited to the process of issuing the access token, but does not extend to the actual MCP traffic between the MCP Client and Server." Brokering governs access, not behaviour. What the agent does with a token it was correctly issued (which tools it calls, what it reads, whether it followed an instruction hidden in a document) is a runtime observability problem federation doesn't touch, and doesn't claim to.
Brokered access changes the question from "which of our thousands of grants exist?" to "what does our policy say?" That's a far better question, and it's the only one an organization can realistically answer at scale. It's also not the whole problem.
The maturity across this stack varies by more than an order of magnitude, and conflating the pieces is how architecture decisions go wrong.
| Component | Status as of July 2026 |
|---|---|
| Shared Signals Framework 1.0, CAEP 1.0, RISC 1.0 | Final Specifications, approved 2 September 2025 |
| Identity Assertion JWT Authorization Grant (XAA) | IETF OAuth WG draft, revision 04, May 2026 |
| Identity Chaining Across Domains | IETF OAuth WG draft, revision 17, July 2026 |
| MCP Enterprise-Managed Authorization extension | Stable extension in modelcontextprotocol/ext-auth |
| IPSIE | v1 draft; no Implementer's Drafts, no Final Specifications |
| SCIM agent schema | Two individual drafts at revision 00; one expired |
Deployment is genuinely beginning rather than hypothetical. Okta announced on 23 June 2026 that it was expanding its Cross App Access ecosystem, with availability for Okta Workforce customers through the Okta Integration Network in August 2026 and early access for Auth0 B2B SaaS customers at the end of July 2026. The named early-adopter list of twenty-five-plus organizations spans requesting applications such as Anthropic, Cursor, Docker and VS Code; resource applications such as Atlassian, Datadog, Figma, Linear, Slack and Supabase; and identity infrastructure including Cloudflare, Keycloak, Stytch and WorkOS. Okta describes XAA as formally incorporated as an official MCP authorization extension and as an open, vendor-neutral protocol, and reports MCP SDK support in TypeScript and Java with Python in progress.
We read that as encouraging, and only partly. A twenty-five-vendor ecosystem is real, and it is not the SaaS estate of an actual enterprise, which runs to hundreds of applications. Cross-App Access requires the resource application's authorization server to implement the profile; an application that hasn't will keep working exactly as it does today, handing out an app-to-app grant the IdP cannot see. Coverage will be partial for years, so the operational reality is a hybrid: a governed path for participating applications, and the old sprawl for the rest, with security value proportional to how much of the estate has actually moved.
Two more caveats. The core specification is a working-group draft that expires 22 November 2026 and may change
before it becomes an RFC, so building against revision 04 means accepting some churn. And Cross-App Access
deliberately doesn't solve the agent-as-actor problem. The draft permits an actor_token on the exchange and
an optional act claim in the ID-JAG, but explicitly declines to define normative processing for either. The
delegation semantics that would let a resource server distinguish an agent from the employee it works for are,
in this profile, future work.
Agent SaaS sprawl is a federation problem wearing a credential-management costume. Every individual grant is defensible. The aggregate is ungovernable, because nothing in the app-to-app model gives any single system a view of the whole, or a lever over it. Telling employees to be more careful doesn't touch a structural property.
We think the fix is moving the decision to the identity provider that already holds the trust relationships,
group memberships, and employment lifecycle, while leaving each application in control of its own access
tokens. That's what Cross-App Access does, via a token exchange producing a short-lived, signed, audience-bound
grant the resource authorization server redeems on its own terms. Shared Signals and CAEP make revocation
travel afterward, and they're finished specifications rather than aspirations. IPSIE is the work of making the
whole enterprise surface interoperable, and it's early. SCIM agent schemas are earlier still, and the owners
attribute they're converging on is the one field that makes agent accountability possible at all.
The test for any agent access architecture is a single question: when an employee leaves on a Friday, what has to happen for every agent acting on their behalf to stop working? If the answer involves a spreadsheet of SaaS admin consoles, the architecture is app-to-app. If the answer is "the IdP stops issuing grants and emits a revocation event," it's brokered. That's the only version that survives actual contact with an enterprise.