> ## Documentation Index
> Fetch the complete documentation index at: https://docs.world.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Cross App Access (XAA)

> Connect agent hosts to reviewed apps with World ID identity delegation and user-controlled permissions.

World IdP supports consumer-controlled identity delegation through its
Cross App Access (XAA) profile of the
[Identity Assertion JWT Authorization Grant draft, revision 06](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-06.html)
(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](https://docs.world.org/agent-pass/step-up.md#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](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-06.html#section-4.3.3)),
and it returns `invalid_grant` when the subject token fails validation, where
revision 06 uses `invalid_request`
([Section 4.3.4.3](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-06.html#section-4.3.4.3)).

Check World IdP's [discovery document](https://auth.world.org/.well-known/openid-configuration)
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](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-06.html#section-4.4.1),
with your authorization-server issuer as audience and RS256 signing keys from
[discovery's `jwks_uri`](https://auth.world.org/.well-known/openid-configuration).

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](https://www.ietf.org/archive/id/draft-ietf-oauth-identity-assertion-authz-grant-06.html#section-4.4)).
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)`](https://docs.world.org/agent-pass/id-tokens-and-identity#store-and-match-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:

```json theme={"system"}
{
  "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](https://auth.world.org/portal). 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](https://docs.world.org/agent-pass/step-up.md#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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.