Cross App Access (XAA)
World IdP supports consumer-controlled identity delegation through its Cross App Access (XAA) profile of the Identity Assertion JWT Authorization Grant draft, revision 06 (opens in a new tab) (ID-JAG, work in progress). A user connects an agent host and chooses the apps it may access. The host can then obtain credentials for those apps without separate World ID authentication for each app. Each app's authorization server issues its own access tokens and controls API permissions. Apps can adopt XAA alongside their existing sign-in.
Requirements
Agent hosts request openid offline_access and receive a refresh token, which
each refresh replaces.
The agent host must support XAA with World IdP as its identity provider. Check this before integrating.
Hosts may register through Client ID Metadata Documents (CIMD), using public
clients or private_key_jwt client authentication.
A host that uses device authorization must be confidential. A CIMD host that
starts device authorization needs private_key_jwt and the device-code grant in
its metadata. A host's login
accepts any World ID account unless its metadata lists default_acr_values with
classes from Accepted accounts.
World IdP's profile differs from revision 06 in two ways: it accepts public hosts
at the token exchange
(Section 4.3.3 (opens in a new tab)),
and it returns invalid_grant when the subject token fails validation, where
revision 06 uses invalid_request
(Section 4.3.4.3 (opens in a new tab)).
Check World IdP's discovery document
for XAA availability. It advertises offline_access, refresh, and ID-JAG exchange
only while XAA is enabled. When disabled, requests for offline_access receive
invalid_scope; refresh and ID-JAG exchange return HTTP 400
unsupported_grant_type.
Your app's authorization server must accept ID-JAGs issued by World IdP and issue access tokens for your MCP server.
Configure your authorization server
Configure your authorization server to trust World IdP, https://auth.world.org.
Accept the ID-JAG JWT bearer grant and apply the
draft's processing rules (opens in a new tab),
with your authorization-server issuer as audience and RS256 signing keys from
discovery's jwks_uri.
When a host authenticates, bind client_id to the authenticated host. Public
hosts send the ID-JAG without client authentication or key binding, which
revision 06 does not allow
(Section 4.4 (opens in a new tab)).
To serve them, identify the host by the ID-JAG's client_id claim. To serve
only confidential hosts, require client authentication.
Hosts and authorization servers must agree on the client identifier; for a host using a Client ID Metadata Document (CIMD), this is the exact HTTPS metadata URL. Register the host at your authorization server with its own credentials, and never accept a client secret that World IdP issued to it.
The ID-JAG's sub is the same pairwise subject World IdP issues to your app in
ID tokens. Its auth_time, acr, and amr describe the user's original World ID
authentication, not a fresh one. Match accounts by
(iss, sub), as for ID tokens.
Your authorization server applies its own scope policy and issues the access
token used to call your MCP server.
Publish RFC 8414 metadata at your authorization server's well-known location,
including the ID-JAG draft's authorization_grant_profiles_supported extension:
{
"issuer": "https://app.example",
"grant_types_supported": ["urn:ietf:params:oauth:grant-type:jwt-bearer"],
"authorization_grant_profiles_supported": ["urn:ietf:params:oauth:grant-profile:id-jag"]
}Enroll your app
Register your app in the developer portal (opens in a new tab). As its owner, use the active app's client settings to submit your authorization-server issuer and the resource URLs of your MCP servers. That issuer identifies the server that issues your access tokens; it is separate from your app's identity sector at World IdP.
World IdP reviews your app's authority over its identity sector, issuer, and resources before users can select it. Enrollment uses the metadata above; no additional verification document or custom metadata field is required. XAA review is independent of catalog publication, and the app picker uses the name recorded at approval.
Several apps can share an authorization server, with separate resources and permissions. A resource URL may be approved for only one app; pending or rejected submissions do not reserve it. World IdP cannot enroll as an app's target authorization server.
Changing the issuer or resources requires a new review. Resource changes preserve saved app permissions; changing the issuer requires renewed user permission. Disabling the app or withdrawing approval stops new ID-JAG exchanges; an exchange already in progress may complete. After a rejection, you can request review again without changing the issuer or resources, and users keep their app selections.
Connect the agent
The host opens World ID authentication and consent, where the user selects the apps it may access. A new app starts unselected, and users can change their selection later.
A host can connect any World ID account. Your app's
accepted accounts decide which
accounts it receives ID-JAGs for: Orb admits Orb accounts, Selfie Check also
admits Selfie Check accounts, and Any account admits every account. Consent marks
apps that do not accept the user's account, and ID-JAG requests for them return
access_denied.
A host's connection expires after 180 days without a successful refresh or ID-JAG exchange. Each one renews that deadline and keeps the original authentication context. The host reconnects interactively after expiry or revocation. Device consent requires an account session authenticated at or after the device request began.
Permissions belong to the exact host client ID, which for a CIMD host is its metadata URL. A new URL, even on the same hostname, is a new host, so hosts should keep it stable. Sessions using the same client ID share app permissions, and reconnecting preserves saved choices. Temporarily unavailable apps retain those choices while their authorization-server issuer stays unchanged.
Manage access
Users can remove an app's permission or disconnect the host at any time. Removing a permission stops new ID-JAG exchanges for that app, and disconnecting stops them for every app; an exchange already in progress may complete. Issued ID-JAGs expire within five minutes, and your access tokens follow your own expiry and revocation policy.