JWT Validation¶
This page covers GuardPost's built-in JWT validation support, including:
- Installing the JWT extra
-
AsymmetricJWTValidatorfor RSA and EC keys -
SymmetricJWTValidatorfor HMAC keys -
CompositeJWTValidator— trying multiple validators - Key sources:
authority,keys_url,keys_provider - The
require_kidparameter - Caching behaviour (
cache_time,refresh_time) -
InvalidAccessTokenandExpiredAccessTokenexceptions - Real-world example: validating tokens from popular identity providers
Installation¶
JWT validation is an optional feature. Install the extra to enable it:
Dependencies
The [jwt] extra pulls in PyJWT and cryptography. These are not
installed by default because many applications use GuardPost only for
policy-based authorization without needing JWT parsing.
AsymmetricJWTValidator¶
AsymmetricJWTValidator validates JWTs signed with asymmetric keys:
| Algorithm family | Algorithms |
|---|---|
| RSA | RS256, RS384, RS512 |
| EC (Elliptic Curve) | ES256, ES384, ES512 |
RSA keys (RS256)¶
EC keys (ES256)¶
Parameters reference¶
| Parameter | Type | Default | Description |
|---|---|---|---|
valid_issuers |
list[str] |
required | Accepted iss claim values |
valid_audiences |
list[str] |
required | Accepted aud claim values |
algorithms |
list[str] |
["RS256"] |
Allowed signing algorithms |
authority |
str |
None |
OpenID Connect issuer URL (auto-discovers JWKS URI) |
keys_url |
str |
None |
Direct JWKS endpoint URL |
keys_provider |
KeysProvider |
None |
Custom keys provider instance |
require_kid |
bool |
True |
Reject tokens that lack a kid header |
cache_time |
int |
10800 |
Seconds before cached keys expire |
refresh_time |
int |
120 |
Seconds before expiry to start proactive refresh |
SymmetricJWTValidator¶
SymmetricJWTValidator validates JWTs signed with HMAC shared secrets
(HS256, HS384, HS512). This is common in server-to-server scenarios
where both sides share a secret.
Secret key types
secret_key accepts a plain str, bytes, or a Secret wrapper object,
so you can keep sensitive values out of your source code by reading them
from environment variables.
CompositeJWTValidator¶
When your application must accept tokens from multiple issuers or signed with
different key types, use CompositeJWTValidator. It tries each validator in
order and returns the first successful result.
Key sources¶
GuardPost supports three ways to supply public keys to AsymmetricJWTValidator.
The most common approach. Provide the issuer URL and GuardPost will
automatically discover the JWKS URI from the .well-known/openid-configuration
endpoint.
Provide the JWKS endpoint URL directly, bypassing discovery.
Implement KeysProvider or use InMemoryKeysProvider for testing.
The require_kid parameter¶
By default, AsymmetricJWTValidator rejects tokens that do not contain a
kid (Key ID) header claim. This is a security best practice: kid lets the
validator select the correct key from the JWKS and avoids trying all available
keys.
When to disable require_kid
Only set require_kid=False when your identity provider does not include kid
in tokens. This forces GuardPost to try every key in the JWKS, which is slower
and slightly less secure.
Caching behaviour¶
Fetching JWKS over HTTP on every token validation would be slow. GuardPost caches keys automatically:
- After the first fetch, keys are cached for
cache_timeseconds (default 3 hours). - When
cache_time - refresh_timeseconds have passed, a background refresh is triggered proactively to avoid downtime during key rotation. - If a token carries an unknown
kid, the cache is bypassed immediately and the JWKS endpoint is re-queried. This handles key rotation without waiting for the cache to expire.
Exceptions¶
| Exception | When raised |
|---|---|
InvalidAccessToken |
The JWT is malformed, the signature is invalid, or the claims are wrong |
ExpiredAccessToken |
The JWT has a valid signature but is past its exp claim |
ExpiredAccessToken is a subclass of InvalidAccessToken, so you can catch
either or both.
Real-world example: popular identity providers¶
Supported identity providers
GuardPost has been tested with the following identity providers:
- Auth0 —
authority="https://<your-domain>.auth0.com/" - Entra ID —
authority="https://login.microsoftonline.com/<tenant-id>/v2.0" - Azure AD B2C —
authority="https://<tenant>.b2clogin.com/<tenant>.onmicrosoft.com/<policy>/v2.0" - Okta —
authority="https://<your-okta-domain>/oauth2/default"
Using the validator as an AuthenticationHandler¶
AsymmetricJWTValidator and SymmetricJWTValidator implement the
AuthenticationHandler interface, so they can be plugged directly into
AuthenticationStrategy:
Last modified on: 2026-03-10 20:06:58