Manage Agents in Your Enterprise

Use this guide when pre-built clients you do not control — Claude Code, VS Code, Cursor, and similar — need to reach third-party MCP servers and APIs you do not protect with Descope, such as HubSpot, Asana, Linear, or Canva, over a standard protocol like MCP.

The agent vendor and the tool vendor each have their own auth. Your enterprise still needs one place to decide which users and agents may reach which tools. Descope is that identity provider: clients sign in once to Descope, and Descope governs access to those third-party servers.

What each agent may reach is decided by policies. You can see and revoke every agent in Agentic Identity.

This page covers the two main ways to make that connection: Cross App Access (XAA) and a gateway. For building MCP servers or agents you write yourself, see Use cases.

Why this matters

Without Cross App Access, every third-party MCP server becomes its own authorization island. Each agent prompts for a separate consent screen, and IT has no single answer to which agents can reach which tools for which users.

The diagrams below use the same five MCP servers. Compare per-server consent with a single central IdP using XAA.

Without Cross App Access (XAA)

Without Cross App Access

Each MCP server manages its own authorization

ClaudeMCP ClientLLinearMCP ServerCCanvaMCP ServerGGitHubMCP ServerNNotionMCP ServerSSlackMCP Server
Starting…5 consent prompts · per-server auth

Without Cross App Access (XAA), each MCP server runs its own OAuth flow and manages access in its own admin console. The user signs in and approves scopes on every server — Linear, then Canva, then GitHub, and so on. There is no central place to see who has access, set policy once, or revoke an agent across every service.

With Cross App Access (XAA)

Cross App Access (XAA)

One sign-in — Descope mints XAA tokens for each server

ClaudeMCP ClientDescopeIssuer · ID-JAGLLinearMCP ServerCCanvaMCP ServerGGitHubMCP ServerNNotionMCP ServerSSlackMCP Server
Connecting…0 consent prompts · XAA tokens

The user signs in once to Descope, your enterprise IdP and ID-JAG issuer. Descope mints a separate assertion for each MCP server the agent is entitled to and connects them all in a single burst. Access is governed centrally through policies you set on each Resource — one place to allow, audit, and revoke agent access across every downstream service.

Two ways to connect

ApproachWhat it doesWhen it fits
XAADescope mints an XAA token (ID-JAG); the third-party AS validates it. Nothing between the agent and the tool.The target supports Cross App Access / ID-JAG.
GatewayAgent calls a gateway you run; Descope is IdP + policy; Connections hold credentials.The target lacks XAA, or you want gateway security controls (prompt-injection detection, central inspection, unified audit, and so on) that XAA does not provide.

These are complementary, not an either/or. Many enterprises use XAA where the vendor supports it and a gateway for everything else — and sometimes a gateway even when XAA is available, when they want those extra controls in the path.

Enforce with XAA

Use this path when the target can validate an XAA token (ID-JAG) — typically a third-party MCP server or API that supports Cross App Access, or an MCP server you protect with Descope (Descope as both issuer and validator; see Use cases → Governing agents internally).

Descope is the IdP your pre-built agent signs into. When the agent needs a target Resource, Descope mints a short-lived assertion for it. The authorization server for that Resource validates the assertion against Descope's public keys and issues an access token. The user never sees a second consent screen on that tool.

Because Descope mints the token per request, it enforces policies in the request path with nothing sitting between your agent and the resource.

How it works

Two things have to be true before an agent can reach a third-party server. The target has to be a Resource in Descope, and a policy has to allow the agent to request an XAA token (ID-JAG) for it.

An XAA token grants access to a Resource, and its resource claim is that Resource's URL, so you register the third-party MCP server as a Resource whose URL matches the server you actually connect to. This is a Resource, not a Connection: you mint a signed assertion the downstream authorization server honors; you are not vaulting a token to replay later.

Which Resources an agent may reach, and with which scopes, is decided by policies grounded in the real users in your tenant. An agent never gets broader access than the user it acts for.

For the full token exchange (curl examples, claims, confidential clients, downstream registration), see How XAA and ID-JAG work → When Descope is the IdP.

XAA setup

Create an MCP Server Resource

In the Descope Console, create a Resource of type MCP Server. Set the MCP Server URL to the exact URL of the third-party MCP server you want to reach. That URL becomes the resource claim of the ID-JAG, and it is the value your agent sends as resource when it requests the assertion.

For example, if Canva's MCP server is https://mcp.canva.com/mcp, set the Resource's MCP Server URL to https://mcp.canva.com/mcp.

Note

The URL must match the downstream server exactly. A trailing-slash or path mismatch produces an assertion the downstream server will reject.

Add the same scopes as the downstream server

Define scopes on the Resource that are identical to the scopes the downstream MCP server expects. The ID-JAG, and the access token the downstream server mints from it, carries these scopes, so they must match what that server publishes.

Check the third-party server's documentation or its OAuth metadata for the scope names, and mirror them on your Resource.

Set Descope as the client's IdP (and pre-register it if needed)

In your MCP client's Enterprise-Managed Authorization (Cross App Access) settings, set the identity provider to Descope, using your project issuer.

The issuer is <base-url>/v1/apps/__ProjectID__, where <base-url> is your region's Descope base URL (for example https://api.descope.com), or your custom domain if you have one set up for your Descope project. The ID-JAG carries the same issuer as your Descope access tokens.

Whether you also pre-register a client depends on the MCP client:

  • Clients that support CIMD (for example Claude Code or VS Code) register with Descope automatically; there is nothing to create.
  • Clients that do not support CIMD must be pre-registered: create the client in Descope and hand its ID and secret to the MCP client.

See the XAA client setup guides for the exact per-client steps.

Write a token-exchange policy

Create a policy that governs who can obtain an ID-JAG for this Resource. Set the grant type to Delegated access (token exchange), then define:

  • Subject: which agents or users the rule applies to (for example a client tag like verified-agent, or a user role).
  • Target: the MCP Server Resource you created, and the allowed scopes on it.

Only subjects a policy allows can exchange their Descope token for an ID-JAG on that Resource, and only for the scopes the policy permits. Because the subject resolves to a real user in your tenant, an agent never gets broader access than that user has.

The token exchange policy is the control point for XAA on the Descope side. It decides which ID-JAG clients reach which XAA-enabled Resources, so a client with no matching policy cannot obtain an assertion at all.

This matters most for manually registered clients. Clients that arrive through CIMD or DCR are granted access to the Resource they registered with, but a client you create by hand in Descope starts with none. If you manually register an ID-JAG client, write the policy in this step or the exchange will fail.

Exchange the token at runtime

The agent calls the token endpoint (RFC 8693) to exchange its Descope token for an ID-JAG scoped to the Resource, then presents that ID-JAG to the downstream server's authorization server to receive an access token. Clients like Claude Code and VS Code do this for you automatically.

XAA client setup guides

These guides walk through configuring Cross App Access (XAA) on popular MCP clients with Descope as the identity provider. They are not gateway setup — for gateways, see Enforce with a Gateway.

Once configured, the client signs in to Descope once and can obtain XAA tokens for every XAA-enabled MCP server you registered, without another prompt.

The same XAA client setup applies when the MCP server is yours and Descope is both issuer and validator — see Use cases → Governing agents internally.

Enforce with a Gateway

Note

Gateway-based enterprise-managed authorization is in early access, and must be enabled by Descope Support for your project.

A gateway sits between the pre-built client and third-party MCP servers or APIs. Use it when:

  • The third party does not support Cross App Access (most servers today — HubSpot, Asana, and similar often only speak ordinary OAuth or API keys), or
  • You want controls XAA alone does not provide: prompt-injection detection, inspection of tool calls in one place, unified audit, tenant-scoped credential routing, and similar gateway security features.

Flow:

  1. Claude Code, VS Code, or another client authenticates to Descope (same IdP story as XAA).
  2. The agent calls your gateway as the MCP entrypoint, not HubSpot or Asana directly.
  3. Descope policies decide whether that agent may use that gateway tool / downstream server.
  4. The gateway pulls the right credential from Connections (OAuth tokens or API keys you or a tenant admin stored) and calls the third-party service.

Descope remains the identity provider and policy decision point. The gateway is the enforcement — and often security — point in the request path.

We work out of the box with agentgateway, or you can bring your own gateway and configure it to use Descope as a PDP.

See MCP Gateways for how to model Resources, Connections, and policies when you build one.

Was this helpful?

On this page