Skip to main content

Accept Identity Assertions from an External IdP

Register an external identity provider as a trusted token issuer so ThunderID accepts the Identity Assertion Authorization Grants (ID-JAGs) it issues and exchanges them for ThunderID-issued access tokens.

When to Use This

Use this when an enterprise identity provider, such as Okta, Azure AD, or another ID-JAG-capable issuer, governs which clients can reach your APIs. Clients arrive at ThunderID already holding an ID-JAG from that identity provider instead of signing in to ThunderID directly. When the protected resource is an MCP server, this is an instance of the Enterprise-Managed Authorization pattern; see Enterprise-Managed Authorization for MCP.

Prerequisites

  • A running ThunderID deployment. See Get Started.
  • Console access.
  • The external identity provider's issuer URI and JWKS endpoint.
  • An application configured as described in Configure the Application.

How Acceptance Works

A client that already holds an ID-JAG from an external identity provider presents it to ThunderID using the jwt-bearer grant, and receives an access token without a separate sign-in step.

Register the Issuer

  1. In the Console, navigate to Connections.
  2. Select Add custom connection.
  3. In the wizard, choose the connection type Trusted Token Issuer.
  4. Name the connection and continue.
  5. In the Add trusted issuer form, fill in:
    • Issuer URI: the external identity provider's issuer identifier. ThunderID matches this against the iss claim of incoming assertions.
    • JWKS endpoint: the URL ThunderID fetches the identity provider's public signing keys from, used to verify assertion signatures.
  6. Leave Enable token exchange at its default (on), or turn it off if you do not also want this issuer's tokens accepted for RFC 8693 token exchange. When token exchange is on, a Trusted token audience field appears; leave it empty for ID-JAG-only use cases.
  7. Turn on Enable Identity Assertion JWT Authorization Grant (ID-JAG). This toggle is off by default.
  8. Click Create connection.
note

Enable token exchange and Enable Identity Assertion JWT Authorization Grant (ID-JAG) are independent trust settings. Enabling one does not enable the other.

Configure the Application

The client that presents ID-JAGs to ThunderID must be a confidential client, and its allowed grant types must include urn:ietf:params:oauth:grant-type:jwt-bearer.

What the Issuer Must Send

The external identity provider's ID-JAG must satisfy these requirements for ThunderID to accept it:

Claim or headerRequirement
typ (header)Exactly oauth-id-jag+jwt
issMatches a connection registered as a trusted ID-JAG issuer
SignatureVerifiable against that connection's JWKS endpoint
audExactly one value, equal to the ThunderID issuer identifier, not the token endpoint URL
client_idEqual to the authenticated client's id
subPresent
exp, iat, jtiPresent. See Limitations for the jti replay caveat.
scopeOptional. When present, the issued access token's scope is the intersection of this claim and the request's scope parameter.
resourceOptional. When present, the request's resource parameter must be a subset of this claim. When absent, any valid resource is accepted.

The client then presents the assertion to ThunderID's token endpoint using the jwt-bearer grant:

curl -X POST https://thunderid.example.com/oauth2/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-d grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer \
-d assertion="$ID_JAG"

Request Parameters

ParameterRequiredValue
grant_typeYesurn:ietf:params:oauth:grant-type:jwt-bearer
assertionYesThe ID-JAG JWT issued by a trusted external identity provider
scopeNoNarrows the assertion's scope claim by intersection
resourceNo, repeatableMust be a subset of the assertion's resource claim; selects one resource server when the assertion authorizes several

Response

FieldValue
access_tokenThe issued access token
token_typeBearer, or DPoP when the request includes a DPoP proof
expires_inToken lifetime in seconds
scopeThe granted scope (intersection of the request scope and the assertion's scope)

No issued_token_type or refresh_token is returned.

How Validation Works

ThunderID validates an incoming assertion in this order:

  1. Checks the typ header is oauth-id-jag+jwt.
  2. Looks up a trusted ID-JAG issuer connection matching the assertion's iss claim. If none matches: invalid_grant - The assertion issuer is not registered as a trusted ID-JAG issuer.
  3. Verifies the signature against that connection's JWKS endpoint.
  4. Validates the time claims. If the assertion has expired: invalid_grant - The assertion has expired.
  5. Checks the aud claim is exactly one value equal to this server's issuer. If not: invalid_grant - The assertion audience must be exactly this server's issuer.
  6. Checks client_id matches the authenticated client. Any other claim failure returns invalid_grant - Invalid assertion.
  7. Confirms the sub claim is present.

Requests missing the assertion parameter fail with invalid_request - Missing required parameter: assertion. A public client attempting the grant fails with invalid_client - The jwt-bearer grant requires a confidential client. An application without the jwt-bearer grant type fails with unauthorized_client - The client is not authorized to use this grant type. A resource parameter that is not a subset of the assertion's resource claim fails with invalid_target - The resource parameter must be a subset of the assertion's resource claim; omitting resource when no default resource server is configured fails with invalid_target - No resource parameter supplied and no default resource server is configured.

The Tokens ThunderID Issues

The issued access token's sub claim is the assertion's subject verbatim, an external identifier rather than a local user id. An idp claim carries the assertion's issuer. ThunderID does not link this subject to a local account or apply attribute mapping, and no refresh token is issued. The token is DPoP-bound when the request includes a DPoP proof. A scope parameter in the request narrows the assertion's scope claim by intersection, and a resource parameter must be a subset of the assertion's resource claim, selecting one resource server when the assertion authorizes several.

Limitations

  • There is no replay cache. ThunderID checks that jti is present but does not track previously seen values, so keep assertion expiry short.
  • No local user mapping occurs. The token's sub is the external identifier as-is.
  • ThunderID does not advertise ID-JAG or Enterprise-Managed Authorization discovery metadata in its well-known documents.
note

This page covers accepting assertions for token issuance. The Secure ThunderID Using a Third-Party Identity Provider guide is a different feature: it validates external tokens directly against ThunderID's own APIs without issuing a new token.

Next Steps

Explore with AI

ThunderID LogoThunderID Logo

Product

DocsAPIsSDKs
© Copyright Linux Foundation Europe.For web site terms of use, trademark policy and other project policies please see https://linuxfoundation.eu/en/policies.