Secure access with enterprise IT oversight between independent applications that communicate with each other is a recognized gap in OAuth 2.0. Enterprises can’t effectively regulate cross-app communication, as OAuth 2.0 consent screens rely on users granting access to their individual accounts. Now, with the advent of AI agents that communicate across systems, the need to solve the gap is even greater – especially given the growing importance of enterprise AI security in protecting sensitive data flows.
This is a companion discussion topic for the original entry at https://developer.okta.com/blog/2025/09/03/cross-app-access
Hi,
I’ve been experimenting with Cross App Access based on this post and the Agent0/Todo0 sample, and I have a question about the required architecture.
In your example, Okta acts as the IdP and there’s a separate authorization server for the resource app (e.g., the Todo0 authorization server). In my setup I have:
My questions are:
-
Can Cross App Access / ID-JAG be used when both the requesting app and the resource app live in the same Okta org, and the resource’s authorization server is also that same org (e.g., via a custom authorization server like /oauth2/default)?
-
Or is it a requirement/recommendation that the resource app have its own authorization server, separate from the enterprise IdP – like in your sample (a custom auth server) or possibly a second Okta org acting as the resource authorization server?
-
If using only a single Okta org is supported, is there a minimal example or configuration you can point to that shows ID-JAG working without a separate non-Okta auth server?
I’m trying to understand the intended deployment model so I can get this working correctly with my own Okta “integrator” instance.
Thanks!
Hi @dharm.ace, thanks for reaching out, and good to know you’re trying out the sample repo.
Regarding your questions:
1. Using Cross App Access / ID-JAG within a single Okta org
Currently, Cross App Access is designed for scenarios where the requesting app and the resource app are third-party to each other, meaning each app has its own authorization server in a separate trust domain. We currently support the model in the Okta Integration Network where you add third-party apps using Okta SSO for your workforce.
So while both apps can live as OIDC clients inside your same Okta org for login, their authorization servers should not be the same. We are actively working on supporting “first-party” / internal-only setups like yours, but that isn’t the intended model yet.
2. Whether the resource must have its own authorization server
Yes – that is the current recommendation.
The requesting app and resource app should each have their own authorization server (their own issuer), separate from the enterprise IdP. This separation is what allows ID-JAG to model cross-app trust correctly.
3. Minimal example using a single Okta org
Right now, there is no minimal example where both apps use the same Okta custom authorization server as their AS. Your scenario falls under “first-party/internal apps,” which is on the roadmap but not available yet.
1 Like
Thank you so much for this clarification. There was some confusion in testing the demo and ID-JAG exchange wouldnt work until we explored the Cross App Access (XAA) for Resource Applications Beta . IDP for Requesting app and Auth Server for Resource app need to be separate trust domain which is where GitHub - oktadev/okta-cross-app-access-mcp: The repository demonstrates a sophisticated enterprise integration pattern where an AI-enabled agent application (Agent0) can securely access resources from a separate todo management application (Todo0) without requiring users to authenticate separately to each system. was not working for us while using same Okta tenant.
Follow up question for the resource Authorization Server. Do the Requesting App IDP and Resource Authorization Server need to be federated as mentioned in this Okta(Requesting App IDP)+Auth0(Resource Auth Server) link Cross App Access (XAA) for Resource Applications Beta?
Regarding the roadmap, is there a page that could be referred to identify the following:
- Support for first-party/internal apps
- Remove dependency on using TODO0 and Agent0 as OIN apps and allowing the ability to Manage connections using Custom OIDC Apps?
I need help understanding whether, in an OAuth/OIDC federation scenario where Okta is the Identity Provider and issues an ID-JAG token (ID-JAG) that the requesting app uses to obtain an access token from a downstream resource server, it is possible to customize the sub claim or include additional claims such as email or other profile attributes in the ID-JAG token. Specifically, I’d like to know if Okta supports overriding the sub value (e.g., mapping it to email, username, or a custom attribute) and whether additional claims can be injected into the ID-JAG token for this delegated authorization flow, and if so, where this should be configured—within the OIDC application settings.
@nithishsubramani Answer to your questions:
-
The sub claim can’t be customized. ID-JAG tokens always use the Okta user’s immutable Okta ID, and there’s no option to remap it to email, username, or any other attribute.
-
Additional claims (like email or profile fields) can’t be added to the ID-JAG token right now. Custom admin-defined claims aren’t supported for this flow.
One thing to keep in mind is that the downstream OIDC step also relies on this same sub value, so both the requesting app and the resource server are expected to use that Okta ID as the stable identifier.
@sohail.pathan Hi, appreciate the demo. I’m facing a few issues when using this. I’ve been trying to set up XAA between an Chat Application and one of our SaaS applications at my company. In order to do this, I believe I would need to be able to exchange the ID-JAG token for an access token from the SaaS application. However, I’ve noticed the ID-JAG token always has the audience listed as localhost:5001 and the client_id is wiki0-at-todo0. I was wondering if there is a way to change this so the audience would be the token_url from the SaaS application? Maybe I am having a misunderstanding of the implementation or these are just preconfigured settings that can’t be changed yet with the beta version.
Hi Team,
I’m implementing the Identity Assertion JWT Authorization Grant (ID-JAG) flow for cross-app access.
Scenario:
- Two resource applications (Product A and Product B) are published as separate OIN apps
- Both share the same Authorization Server issuer URL: https://api.vendor.example.com/
- A requesting app (Agent App) needs to get an ID-JAG to access either Product A or Product B
Token Exchange Request:
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
&requested_token_type=urn:ietf:params:oauth:token-type:id-jag
&audience=https://api.vendor.example.com/
&scope=product_a.read
&subject_token=<id_token>
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
How does Okta identify which app (Product A or Product B) to apply the access policy for when:
- The audience parameter is the same for both apps
- The resource parameter (RFC 8707) is not supported in OIN submission
- Only scope values differ between the requests
I understand that the resource parameter (RFC 8707) can be used to differentiate between apps that share the same issuer URL.
Is there a provision to configure a resource identifier when publishing an OIN app so that Okta can use it to identify which app’s policy to apply during ID-JAG issuance?
What is the mechanism Okta uses to differentiate between these two apps during ID-JAG issuance?
Thanks!
In the ID-JAG RFC, it is mentioned that the IdP can include the email attribute as a claim. Could you please confirm if this is the expected approach?
@nithishsubramani
Apologies for the late response on this!
First, a clarifying point — if both Product A and Product B share the same Authorization Server issuer URL, they don’t necessarily need to be two separate OIN apps. A single OIN app can
represent both products under one issuer. Is there a specific reason they need to be published as two separate apps?
That said, to answer your questions:
How does Okta differentiate between apps during ID-JAG issuance?
Okta uses a combination of:
- App assignments - which apps the user is assigned to
- SSO session - which app the user has actually signed into
- Manage Connections - which resource app is linked to the requesting app (Agent App)
These together determine which app’s policy applies when issuing the ID-JAG.
On the resource parameter:
Currently, the ID-JAG flow passes through the resource parameter as-is. If you include it in your token exchange request, that value will appear as a claim in the issued ID-JAG. Your
Authorization Server can then read this claim to determine which product (A or B) the ID-JAG is intended for and apply the right access rules on your end.
So even though the resource parameter (RFC 8707) isn’t part of OIN submission today, you can still use scopes (as you’re already doing) and the resource parameter in the token exchange request to signal which product the access is for, and handle the differentiation at your Authorization Server.
Thanks!
Okta doesn’t include email in the sub claim. This is a very recent addition to the spec and it is optional, we have not added it to the sub claim.
but in our case we only provide an MCP server and act as an MCP Gateway, and we do not have a UI. Because of this, we will not support user SSO flows, since there is no user interface where users can perform SSO authentication.
Given this architecture, I have a question regarding user identification using IDJAG.
Currently, IDJAG does not contain the email identifier, even though the IDJAG specification mentions that the email claim can be optional. Because of this, it is unclear how we should reliably identify the user.
Questions:
-
In this scenario, how should we obtain the user details when we only receive IDJAG?
-
Should we call the /userinfo endpoint with IDJAG Jwt Token to retrieve additional user attributes such as email?
-
What is the best architectural approach to solve user identification for a service that acts only as an MCP Gateway and does not support user SSO?
Could you please clarify the recommended way to approach this problem?