Skip to content

Token Validation

JWT validation with optional OpenID Connect auto-discovery.

Configuration

TokenValidationConfig(perform_disco, key=None, audience=None, algorithms=None, issuer=None, subject=None, options=None, claims_validator=None, require_https=True, leeway=None) dataclass

Configuration for JWT token validation.

Attributes:

Name Type Description
perform_disco bool

Whether to perform discovery to fetch JWKS and issuer

key dict | None

Public key for JWT verification (dict with 'kty', 'n', 'e' for RSA)

audience str | None

Expected audience claim(s) in the token

algorithms list[str] | None

List of allowed signing algorithms (e.g., ['RS256'])

issuer str | list[str] | None

Expected issuer claim. A single string or a list of accepted issuers for multi-tenant validation.

subject str | None

Expected sub claim. Validated after decoding.

options dict | None

Additional PyJWT decode options (e.g., {'verify_exp': False})

claims_validator Callable | None

Optional callable for custom claims validation. Can be sync: Callable[[dict], None] or async: Callable[[dict], Awaitable[None]] (in async context) Should raise an exception if validation fails. The decoded token claims dict is passed as the only argument.

leeway float | None

Clock skew tolerance in seconds for exp and nbf claims. Useful when clocks between the issuer and this server are not perfectly synchronized.

Examples:

>>> # Multi-tenant with clock skew tolerance
>>> config = TokenValidationConfig(
...     perform_disco=True,
...     audience="my-api",
...     issuer=[
...         "https://idp1.example.com",
...         "https://idp2.example.com",
...     ],
...     leeway=30,
... )
>>> # Custom claims validation
>>> def validate_custom_claims(claims: dict) -> None:
...     if claims.get("role") != "admin":
...         raise ValueError("User is not an admin")
>>>
>>> config = TokenValidationConfig(
...     perform_disco=True,
...     claims_validator=validate_custom_claims,
... )

Sync API

validate_token(jwt, token_validation_config, disco_doc_address=None, http_client=None)

Validate a JWT token.

Parameters:

Name Type Description Default
jwt str

The JWT token to validate

required
token_validation_config TokenValidationConfig

Token validation configuration

required
disco_doc_address str | None

Discovery document address (required if perform_disco=True)

None
http_client HTTPClient | None

Optional managed HTTP client. When None, uses the thread-local default with response caching. When provided, caching is bypassed and the injected client is used directly.

None

Returns:

Name Type Description
dict dict

Decoded token claims

Raises:

Type Description
TokenValidationException

If token validation fails

ConfigurationException

If configuration is invalid

Async API

validate_token(jwt, token_validation_config, disco_doc_address=None, http_client=None) async

Validate a JWT token (async).

Parameters:

Name Type Description Default
jwt str

The JWT token to validate

required
token_validation_config TokenValidationConfig

Token validation configuration

required
disco_doc_address str | None

Discovery document address (required if perform_disco=True)

None
http_client AsyncHTTPClient | None

Optional managed HTTP client. When None, uses the module-level singleton with response caching. When provided, caching is bypassed and the injected client is used directly.

None

Returns:

Name Type Description
dict dict

Decoded token claims

Raises:

Type Description
TokenValidationException

If token validation fails

ConfigurationException

If configuration is invalid