Skip to content
Customer Identity · available nowBuild your first Test integration.Create a Test project
NamoID
All posts
NamoID Blog

How to Validate a JWT: Signature, Claims and Access

Validate signed JWTs with a configured issuer, trusted JWKS, expected audience, required claims, and token profile. Run rejection and rotation tests.

Validate a JWT against a configured issuer, key source, audience and token profile before using its claims. For a signed access token, verify the signature and required claims. Then enforce the permissions for the requested operation.

Decoding reveals data. Validation establishes whether the token meets the rules for your service. This guide uses a signed RS256 access-token example and includes runnable rejection tests.

Choose the expected token profile

A JWT can be signed or encrypted. This tutorial handles a compact signed JWS with three segments. Its encoded payload is readable. An encrypted JWE has a different representation and processing model. Accept only the profile your endpoint supports. JWT specification.

An ID token describes authentication to its client. It should not substitute for an access token at an unrelated API. Use access-token and ID-token boundaries when selecting validation rules.

Configure trust outside the token

ValueTrusted source
Expected issuerApplication configuration
JWKS URLReviewed issuer metadata or pinned configuration
Allowed signing algorithmsThe selected token profile
Expected audienceThe receiving API's configured identifier
Required claimsThe profile and application policy
Required permissionThe requested application operation

Do not fetch an arbitrary jku, certificate URL or issuer URL supplied inside an unverified token. Treat kid as a selection hint within an already trusted key set. Put limits on unknown-key refresh attempts.

Verify a signed API token

The following example assumes an approved RS256 issuer and a fixed JWKS URL. The audience is the API resource, not an arbitrary browser client identifier.

import jwt
from jwt import PyJWKClient
 
jwks = PyJWKClient("https://issuer.example.test/oauth/jwks.json")
 
def read_access_token(token: str) -> dict:
    header = jwt.get_unverified_header(token)
    if header.get("alg") != "RS256" or header.get("typ") != "at+jwt":
        raise ValueError("Unexpected token profile")
    key = jwks.get_signing_key_from_jwt(token)
    claims = jwt.decode(
        token,
        key.key,
        algorithms=["RS256"],
        issuer="https://issuer.example.test",
        audience="https://orders.example.test",
        leeway=30,
        options={"require": ["exp", "iat", "iss", "aud", "sub", "client_id", "jti"]},
    )
    if claims.get("token_use") != "access":
        raise ValueError("Unexpected token use")
    return claims

Here, token_use=access is an issuer-specific requirement. at+jwt identifies the expected access-token type. Confirm the actual issuer profile before adapting either rule. The 30-second leeway is an example policy, not a universal maximum. OAuth JWT access-token profile, PyJWT usage.

The header check only rejects an unexpected format. The signature and claim checks establish acceptance. Require claims explicitly when absence would otherwise be allowed by the library.

Enforce authorization after validation

A valid token can still lack permission to read an order. Check the granted scope and application resource policy after validation. Bind the decision to the active tenant or organization where relevant.

Do not use a display name, email suffix or missing role as a default administrator assignment. The multi-tenant access guide covers this boundary.

Run rejection tests before accepting traffic

Download the JWT validation example. It uses generated synthetic keys and a configured local key set. Its self-test does not require a live issuer.

python jwt-validation-example.py

The fixture checks valid tokens and rejects wrong audiences, wrong issuers, expired tokens, missing claims, incorrect token use and untrusted keys. It also tests a rotated key after an approved key-set update.

For production, add a real approved issuer test and a bounded JWKS refresh policy. Keep old verification keys only for the intended overlap period. Record failures without storing raw tokens.

Track standards status accurately

RFC 8725 supplies published JWT security guidance. Its revision, draft-ietf-oauth-rfc8725bis-10, remained an Internet-Draft in the RFC Editor queue when checked on 12 November 2026. Treat draft changes as work in progress until publication. Published JWT BCP, revision status.

Review your verifier with NamoID

NamoID's current user access tokens use RS256, typ=at+jwt and token_use=access. Their audience identifies the authorized resource or userinfo endpoint. Management access uses a separate token-use value and audience.

Our engineers can help review your issuer configuration and API policy. Share your stack, expected audience and a synthetic failure case in Slack for an early response. Contact the NamoID team