Skip to content

Agents & MCP

Claude signs user logins so plugins auto-connect, in beta

7 min read

Written by an AI model from the linked sources and checked against them by a second model. How we work

Video: x.com

Anthropic on November 3 put into beta a mode where Claude signs the user’s identity itself. On Team and Enterprise plans, plugins whose MCP servers trust Claude as an issuer now connect when the user logs in to Claude, with no OAuth consent screen. Because the signed token comes from Claude, customers with no identity provider of their own can use it. Organizations that sign in to Claude through Okta can’t, and a connector supports it only after its authorization server accepts and validates Claude’s tokens, as Anthropic’s connector documentation lays out.

Fourteen services already support it: Amplitude, Apollo.io, Atlassian, Datadog, Dropbox, Figma, Granola, HubSpot, Linear, Mixpanel, Notion, PagerDuty, Semrush and Supabase. The version where the customer’s own identity provider signs the token was already generally available for MCP connectors. The beta adds Claude as a second possible signer, and that is what drops the requirement for an identity provider. Asana, Canva and Slack were on the list for the identity-provider version but are not among the fourteen named for the Claude-issued beta.

How the exchange works

When a user invokes your connector, Claude gets a signed identity assertion for that user and sends it to your token endpoint. Your authorization server checks it and returns an access token, all in one back-channel request with no browser redirect. Your MCP server ends up with the same kind of bearer token it would get from the interactive OAuth flow. Under the hood this is the JWT bearer authorization grant from RFC 7523, an IETF standard from May 2015 for exchanging a signed JWT for an OAuth access token. The assertion follows the Identity Assertion JWT Authorization Grant (ID-JAG) profile, and the flow itself is defined by MCP’s enterprise managed authorization extension. The token format and the exchange are the same whether Claude or the identity provider signs, so one implementation handles both.

It also works with lazy authentication, where the server asks for credentials only when a protected tool is called. Normally, when your server returns 401 with a WWW-Authenticate header, Claude shows its inline Connect card. If the organization has managed auth set up for your connector, Claude instead runs the silent exchange and retries the tool call. Fully authless servers are left out, because they never return a 401 that Claude could respond to.

If your MCP server sits on a hosted identity platform, you may not have to write any code. You do have to confirm three things: the platform supports the JWT bearer grant, it runs every validation check Anthropic lists, and it lets you register a trusted issuer URL that isn’t the customer’s identity provider. Anthropic says some commercial authorization servers and identity platforms don’t support the grant yet.

The checks your token endpoint runs

Before running any check, your server has to work out which workspace the assertion is for. If you identify customers by your own tenant ID and the assertion includes an aud_tenant claim, use the workspace it names. A Claude-issued assertion includes that claim when the customer’s admin typed your tenant ID into Claude’s setup, and Claude doesn’t check the value. If there’s no tenant claim, use the workspace that registered the issuer, and reject the request if no workspace or more than one did.

The issuer check is an exact string match. Anthropic warns that matching on a prefix or host lets in other customers’ users. That risk is concrete for Claude-issued tokens: every Claude issuer URL has the form https://identity.anthropic.com/issuers/<issuer-id>, and every Claude issuer signs with the same keys. A valid signature therefore doesn’t tell you which Claude organization a token belongs to. Only iss does.

Fetch keys from the jwks_uri in the issuer’s /.well-known/openid-configuration document, after confirming that the document’s issuer matches. Ignore any key or key URL in the token header, don’t pin a single key, and fetch again when a token names a kid you haven’t seen. A Claude issuer’s discovery document contains only issuer and jwks_uri, with no authorization or token endpoint. A validator that expects a full OpenID Connect provider configuration will choke on it, so read those two fields yourself.

The remaining rules are strict. Accept ES256 and RS256 and nothing else, including none and HS256; Claude-issued tokens use ES256. The typ header must be oauth-id-jag+jwt. aud must equal your authorization server’s own issuer value, and it can arrive as a string or a one-element array. client_id must match the request. Allow at most 60 seconds of clock skew. Accept each jti only once per issuer, and if you can’t tell whether a jti has been used, reject the request. Every failed check returns invalid_grant. The access token you issue covers only the resolved workspace, even if the same user belongs to others.

What a Claude-issued token vouches for

The token says two things: the user is a current member of the customer’s Claude organization, and here is the lowercase email on their Claude account. It doesn’t say whether they signed in through the company’s identity provider or used multi-factor authentication, and it carries no groups and no sub_id. Look users up by email among the members of the resolved workspace: compare the full address, ignore case, and leave dots and plus tags as they are. The sub value is different under each issuer, so it can’t serve as a lookup key. If no member has that address, reject the request, or create the user only when the address is on a domain the workspace has verified with your service.

Atlassian, one of the launch services, documents the admin side in its support guide, where the feature also goes by Cross App Access (XAA). The admin turns on Enable auto sign-in under Connectors in Claude Admin, picks the Atlassian MCP, sets the identity source to Claude-issued, copies the issuer URL and enters the Atlassian cloudId as the Tenant ID. Atlassian says that field is required for the integration to work. This option doesn’t need an Okta XAA Resource application. Since Claude passes the tenant ID along without checking it, the connector is what has to confirm it.

When a user leaves

Each Claude-issued assertion expires within a minute, and Claude signs a new one, with a new jti, for every sign-in and renewal. That means a short access-token lifetime, such as one hour, doesn’t force users to log in again, because Claude renews in the background. With the identity-provider version, Claude renews using a long-lived refresh token from the provider, and the connection lasts as long as that token stays valid.

When someone is removed from the customer’s Claude organization, Claude stops signing assertions for them. Access tokens you have already issued stay valid, so your access-token lifetime sets how long a removed user keeps access to your service.

Testing before customers turn it on

End-to-end tests need a Claude organization on a Team or Enterprise plan, signed in as an Owner or Primary Owner. For the Claude-issued path, the organization must not use Okta for SSO. It doesn’t need SSO, a verified domain or an identity provider, so a Team organization created just for testing works as is. While you’re still building, Okta’s cross-app access playground can exercise your authorization server and MCP server without any Claude organization.

No comments yet. Be the first.

Join the conversation

Sign in to leave a comment. It appears after moderation.