JWT Validator Policy

Important: This page describes Classic APIM. For APIM 3.0, refer to API Management 3.0.
Authenticates requests with a JSON Web Token (JWT) token. API version or Proxy consumers must use their JWT credentials to sign their JWT. The policy automatically detects the signing algorithm using the JWT token header and key. You can use a policy with a JWT Validator policy for authentication with the Try it out feature in Developer Portal.
You can configure the policy to extract values from the JWT claim to add and pass in the request header to the underlying pipeline. The token value can then be passed to downstream systems. Tokens passed in the request header don't appear in logs nor are they visible in Monitor.
Before allowing API access to the consumer, the policy does the following:
  • Verifies the token signature with the configured key.
  • Checks the expiration time.
If the signature is valid and the token hasn't expired, the policy processes the request. Otherwise, it returns HTTP 401 Unauthorized.

To restrict access to the consumers you intend, use the Authorize by Role policy. The Roles Expression field locates the role in the token claim, and the Role field in the Authorize by Role policy takes the role name that the claim holds, such as admin.

Policy execution order

This JWT Validator policy authenticates the request and provides the security context that downstream policies (such as Authorize by Role) require. If another authentication policy has already set the security context, this policy skips itself.

Supported algorithms

This policy only supports the following cryptographic algorithms:
  • Elliptic Curve Digital Signature Algorithm (ECDSA): ES256, ES384, ES512
  • Rivest–Shamir–Adleman (RSA): RS256, RS384, RS512
  • Hash-Based Message Authentication Code using SHA (HSA): HS256, HS384, HS512

Tokens from Microsoft Entra ID

With Microsoft Entra ID as the identity provider, you set up Microsoft Entra ID to issue an access token for your API, and consumers pass that token with each request. The policy verifies the token against the signing keys that your Microsoft Entra tenant publishes.

Set Key Input Format to URL and enter your Microsoft Entra tenant's key endpoint in the URL field: https://login.microsoftonline.com/<tenant-id>/discovery/v2.0/keys, where <tenant-id> is your Microsoft Entra Directory (tenant) ID.

To make Microsoft Entra ID issue tokens for your API, expose an API on your app registration. Exposing the API gives it an application ID URI, such as api://<api-app-id>, and a client that requests a scope under that URI receives an access token that names your API. Don't use the following Microsoft Entra ID tokens:
  • An ID token, which Microsoft Entra ID issues to authenticate a user in a client application. It isn't proof that the client can call your API.
  • An access token for Microsoft Graph. Microsoft signs Graph tokens with keys that it doesn't publish on your Microsoft Entra tenant's key endpoint, so the policy can't verify the signature and returns HTTP 401.

Any method that returns such a token works, because the policy validates the token it receives and not how the client obtained it. The following request is one way: a client calling the API as itself, rather than on behalf of a signed-in user, uses the client credentials grant, which accepts only the .default scope.

curl --location --request POST \
  "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token" \
  --header "Content-Type: application/x-www-form-urlencoded" \
  --data-urlencode "grant_type=client_credentials" \
  --data-urlencode "client_id=<client-id>" \
  --data-urlencode "client_secret=<client-secret>" \
  --data-urlencode "scope=api://<api-app-id>/.default"

Replace the placeholders in the request with values from Microsoft Entra ID:

  • <tenant-id>: Your Microsoft Entra Directory (tenant) ID.
  • <client-id>: The Application (client) ID of the client's app registration.
  • <client-secret>: A client secret that you generate in the client's app registration.
  • <api-app-id>: The Application (client) ID of the app registration that exposes your API. If you changed the application ID URI from its default, replace api://<api-app-id> with that URI.

The response contains an access_token value, which the client sends in one of the locations that Extract into $token lists.

To check which token a client sends, decode it at https://jwt.ms. The aud (audience) claim names your API when the client sent the right token.

Note: If the aud claim identifies your API and requests still fail, check whether the app registration has SAML single sign-on enabled. Microsoft Entra ID then signs tokens with the SAML signing certificate, which your Microsoft Entra tenant's key endpoint doesn't publish.

Other token providers

Any identity provider works similarly to Microsoft Entra ID. Enter the provider's JSON Web Key Set (JWKS) URL in the URL field, and have consumers send an access token that the provider issued for your API rather than an ID token. The policy fetches keys from that URL, so the provider must publish the key that signed the token there and must sign with one of the supported algorithms. Otherwise the policy can't verify the signature and returns HTTP 401.

The JWT policy contains these common properties, the others depend on whether you select the RAW_TEXT or the URL format.
Field Name Description
When this policy should be applied An expression that defines one or more conditions that must be true for the policy to execute.

Example: The expression request.method == "POST" causes the policy to execute only on POST requests.

Key Input Format Select one of the following two options:
  • RAW_TEXT
  • URL
Note: The option you select determines the subsequent fields.

Default value: RAW_TEXT

Raw text format properties

With the RAW_TEXT format selected, the following fields display.

Field Name Description
Key

Paste the contents of the public key, which can be a PEM Encoded key, a JSON Web Key (JWK), or a Client Secret.

Default value: N/A

Example: -----BEGIN PUBLIC KEY-----

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu1SU1LfVLPHCozMxH2Mo

4lgOEePzNm0tRgeLezV6ffAt0gunVTLw7onLRnrq0/IzW7yWR7QkrmBL7jTKEn5u

+qKhbwKfBstIs+bMY2Zkp18gnTxKLxoS2tFczGkPLPgizskuemMghRniWaoLcyeh

kd3qqGElvW/VDL5AaWTg0nLVkjRo9z+40RQzuVaE8AkAFmxZzow3x+VJYKdjykkJ

0iT9wCS0DRTXu269V264Vf/3jvredZiKRkgwlL9xNAwxXFg0x/XFw005UWVRIkdg

cKWTjpBP2dPwVZ4WWC+9aGVd+Gyn1o0CLelf4rEjGoXbAAEgAqeGUxrcIlbjXfbcmwIDAQAB

-----END PUBLIC KEY-----

Extract into $token Required. Use one or more of the following properties to specify where to find the token in the request. The policy checks locations in this order and uses the first match: Custom Header Keys, Custom Query String Parameter Keys, Authorization Header, Custom Cookie Key. If the token isn't found in any location, this policy passes the request to the next policy.
Custom Header Keys The name of one or more header keys to check for the token. Click + to add more.

Default value: N/A

Example: x-jwt-key

Custom Query String Parameter Keys The names of one or more query parameter keys to check for the token. Click + to add more.

Default value: N/A

Example: Auth

Authorization Header Type If the key is in the Authorization header, this value is used as the “type” to check. Bearer is the correct type for JWTs.

Default value: Bearer

Extract User Info Required. Expressions that extract the user identity and role from the JWT claims. Both fields use JSONPath syntax where $ represents the root of the claims document.
User ID Expression Required.Where to find the user ID in the token claim.

Default value: N/A

Example: $sub

Roles Expression Required. Where to find the user role in the token claim.

Default value: N/A

Example: $role

Headers to add Optional. Name-value pairs to pass information from the token in the request header to pipeline parameters. For example, you might pass the user ID from the token claim so that the underlying pipeline can retrieve it in a parameter.

Example:

To pass the role and token in the header:
  • Name: role Value: $aud
  • Name: tempKey Value: request.uri.path
  • Name: keyID Value: $kid
  • Name: all Value: $
To retrieve the token in pipeline parameters, add a Mapper Snap and map the header values:
  • _ROLE > $aud
  • _TEMPKEY > $tempKey
  • _KEYID > $kid
  • _ALL > $all
Description The purpose of the policy.

URL format properties

With the URL format selected, the following properties are available.

Field Name Description
URL

Enter the URL endpoint or click = to enter an expression to obtain the key.

Default value: N/A

Example: https://login.microsoftonline.com/%3Ctenant%3E/discovery/v2.0/keys

Extract Keys from URL A JSONPath expression that extracts the key material from the URL response. The default $ uses the entire response body as the key set.
Note: This policy supports a list of JWK keys or a single JWK key and verifies against the kid field in the JWT header. If you pass in a list of keys, only the key whose kid matches the JWT header’s kid is used for verification.

Default value: $

Example: $keys

Extract into $token Required. Use one or more of the following properties to specify where to find the token in the request. The policy checks locations in this order and uses the first match: Custom Header Keys, Custom Query String Parameter Keys, Authorization Header, Custom Cookie Key. If the token isn't found in any location, this policy passes the request to the next policy.
Custom Header Keys The name of one or more header keys to check for the token. Click + to add more.

Default value: N/A

Example: x-jwt-key

Custom Query String Parameter Keys The names of one or more query parameter keys to check for the token. Click + to add more.

Default value: N/A

Example: Auth

Custom Cookie Key The names of one or more cookie keys to check for the token. Click + to add more custom cookies.
Tip: In the request, the cookie value should contain the JWT.

Default value: N/A

Example: My_jwt

Authorization Header Type If the key is in the Authorization header, this value is used as the “type” to check. Bearer is the correct type for JWTs.

Default value: Bearer

Extract User Info Required. Expressions that extract the user identity and role from the JWT claims. Both fields use JSONPath syntax where $ represents the root of the claims document.
User ID Expression Required.Where to find the user ID in the token claim.

Default value: N/A

Example: $sub

Roles Expression Required. Where to find the user role in the token claim.

Default value: N/A

Example: $role

Headers to add Optional. Name-value pairs to pass information from the token in the request header to pipeline parameters. For example, you might pass the user ID from the token claim so that the underlying pipeline can retrieve it in a parameter.

Example:

To pass the role and token in the header:
  • Name: role Value: $aud
  • Name: tempKey Value: request.uri.path
  • Name: keyID Value: $kid
  • Name: all Value: $
To retrieve the token in pipeline parameters, add a Mapper Snap and map the header values:
  • _ROLE > $aud
  • _TEMPKEY > $tempKey
  • _KEYID > $kid
  • _ALL > $all
Description The purpose of the policy.