An Azure service that provides a hybrid, multi-cloud management platform for APIs.
How to validate JWT with only a public key
Hello,
we have an APIM policy attempting to validate incoming JWT using public key modulus, exponent and id.
This policy however seems to not validate JWT signature for some reason. When I change key modulus, exponent or id, the validation still passes and request is forwarder to backend. If I change audience or issuer in the policy, the validation fails as expected.
What is the proper way to validate incoming JWT when we only have acess to public key of the identity provider?
Azure API Management
1 answer
Sort by: Most helpful
-
AI answer
2026-05-12T09:12:17.8233333+00:00 Use the
validate-jwtpolicy with an asymmetric issuer signing key configured from the public key. The signature is validated against the public key; if the modulus/exponent are wrong, validation must fail.To validate with only a public key, configure one of these options in the
validate-jwtpolicy:- Use an OpenID configuration endpoint (recommended)
<validate-jwt header-name="Authorization" require-scheme="Bearer"> <openid-config url="https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration" /> <audiences> <audience>api://your-api-app-id</audience> </audiences> <issuers> <issuer>https://login.microsoftonline.com/{tenant}/v2.0</issuer> </issuers> </validate-jwt>openid-configcauses API Management to pull the JWKS (public keys) from the identity provider and use them to validate the JWT signature. This is the simplest and most robust way when only the public key is available.- Use modulus and exponent directly
If the OpenID configuration endpoint cannot be used, specify the RSA public key via
issuer-signing-keyswithnande:<validate-jwt header-name="Authorization" require-scheme="Bearer"> <issuer-signing-keys> <key id="your-kid" n="{base64url-modulus}" e="{base64url-exponent}" /> </issuer-signing-keys> <audiences> <audience>api://your-api-app-id</audience> </audiences> <issuers> <issuer>https://your-issuer</issuer> </issuers> </validate-jwt>Key points to ensure signature is actually validated:
- Do not disable signing
Make sure
require-signed-tokensis not set tofalse:<validate-jwt header-name="Authorization" require-scheme="Bearer" require-signed-tokens="true"> ... </validate-jwt>If
require-signed-tokensisfalse, the token is accepted without signature validation, which matches the behavior described (changing key values has no effect).- Configure
issuer-signing-keyscorrectly
Within
issuer-signing-keys:- Use
<key id="..." n="..." e="..." />for an RSA public key. -
nandemust be Base64url-encoded values of the modulus and exponent. - If
idis set, it is matched to the token’skidclaim; if nokidmatches, API Management will try all keys.
If the key element is misconfigured but
require-signed-tokensisfalse, the token still passes. Withrequire-signed-tokens="true", a mismatchedn/ecauses validation to fail.- Ensure other required elements are present
For full validation, configure:
<audiences> <audience>...</audience> </audiences> <issuers> <issuer>...</issuer> </issuers>and keep
require-expiration-timeat its defaulttrueunless there is a specific reason to allow tokens withoutexp.- Alternative: certificate-based public key
If the public key is available as a certificate uploaded to API Management, use
certificate-idinstead ofn/e:<issuer-signing-keys> <key certificate-id="your-cert-id" /> </issuer-signing-keys>This also validates the signature using the public key from the certificate.
In summary, to ensure the JWT signature is actually validated when only a public key is available, configure
validate-jwtwith eitheropenid-configorissuer-signing-keys(n/eorcertificate-id) and keeprequire-signed-tokens="true". If changing modulus/exponent has no effect, the policy is likely not using those keys (for example, becauserequire-signed-tokensis disabled or the token is not signed with an asymmetric algorithm supported by the policy).
References:
- Validate JWT
- Validate JWT > Attributes
- Validate JWT > Elements
- Validate JWT > Usage
- Protect an API in Azure API Management using OAuth 2.0 authorization with Microsoft Entra ID
AI-generated content may be incorrect. Read our transparency notes for more information.