jwt
Policy Information Point for validating and monitoring JSON Web Tokens (JWT). Tokens are read securely from subscription secrets. Attributes update automatically based on token lifecycle events such as maturity and expiration.
This Policy Information Point validates JSON Web Tokens and monitors their validity state over time.
JWT tokens are read securely from subscription secrets, never from the policy evaluation context. Public key configuration is read from policy variables.
Token Access
Use the <jwt.token> environment attribute to access token data:
policy "require valid jwt"
permit
<jwt.token>.valid;
policy "role check"
permit action == "admin:action";
"admin" in <jwt.token>.payload.roles;
<jwt.token>.validity == "VALID";
The attribute returns an object with:
header: Decoded JWT header (algorithm, key ID, etc.)payload: Decoded JWT payload with time claims converted to ISO-8601valid: Boolean indicating current validityvalidity: Detailed validity state string
Signature Verification
Tokens are verified against all standard JWS algorithms:
- RSA: RS256, RS384, RS512, PS256, PS384, PS512
- ECDSA: ES256, ES384, ES512
- HMAC: HS256, HS384, HS512
Public keys for signature verification are sourced from:
- A whitelist of trusted keys configured in policy variables
- A remote key server that provides public keys on demand
Time-based Validation
Tokens are validated against time claims:
nbf(not before): Token becomes valid at this timestampexp(expiration): Token becomes invalid at this timestamp
Validity states transition automatically, triggering policy re-evaluation.
Configuration
Configure through policy variables in pdp.json:
{
"variables": {
"jwt": {
"secretsKey": "jwt",
"clockSkewSeconds": 60,
"publicKeyServer": {
"uri": "http://authz-server:9000/public-key/{id}",
"method": "GET",
"keyCachingTtlMillis": 300000
},
"whitelist": {
"key-id-1": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."
}
}
}
}
The secretsKey field specifies which key in subscription secrets holds the JWT token.
Defaults to "jwt" if omitted.
The clockSkewSeconds field specifies clock skew tolerance in seconds for time claim
validation (RFC 7519 recommends allowing some leeway). Defaults to 0 (exact comparison)
if omitted. Set to 60 for typical server deployments.
The maxTokenLifetimeSeconds field specifies the maximum allowed token lifetime in seconds.
If set and the token’s lifetime (exp minus iat, or exp minus now if iat is absent)
exceeds this value, the token is treated as NEVER_VALID. Defaults to 0 (disabled) if omitted.
Validity States
VALID: Token signature is trusted and time claims are satisfiedEXPIRED: Token has passed its expiration timeIMMATURE: Token has not yet reached its not-before timeNEVER_VALID: Token’s not-before time is after its expiration timeUNTRUSTED: Signature verification failed or public key unavailableINCOMPATIBLE: Token has critical header parametersINCOMPLETE: Required claims (key ID) are missingMALFORMED: Token is not a valid JWT structureMISSING_TOKEN: No token found under the configured secrets key
Limitations
- Only JWS (JSON Web Signature, RFC 7515) tokens are supported. JWE (JSON Web
Encryption, RFC 7516) tokens are not supported. JWE encrypts the token payload
for confidentiality and uses a fundamentally different structure (5 parts instead
of 3) requiring private decryption keys. Attempting to use a JWE token will
result in
MALFORMEDvalidity state. JWE adoption is low as most deployments rely on TLS for transport confidentiality. - Token revocation is not checked. JWTs are validated statelessly based on cryptographic signature and time claims only. A revoked token remains valid from this PIP’s perspective until it expires. Applications requiring revocation checks should use OAuth2 Token Introspection (RFC 7662) at the application layer or a dedicated introspection PIP.
- Audience (
aud) and issuer (iss) claims are not validated by the PIP. These are exposed in<jwt.token>.payloadfor policy authors to check directly in policy conditions.
token
<jwt.token(TEXT secretsKeyName)> reads a JWT from subscription secrets using the specified
key name and returns an object containing the decoded token data and its current validity state.
This overload allows reading tokens stored under a custom key in subscription secrets.
Example:
policy "access token check"
permit
<jwt.token("accessToken")>.valid;
token
<jwt.token> reads a JWT from subscription secrets using the configured default secrets key
and returns an object containing the decoded token data and its current validity state.
The returned object has the structure:
{
"header": { "kid": "key-1", "alg": "RS256" },
"payload": { "sub": "user123", "roles": ["admin"], "exp": "2026-02-15T..." },
"valid": true,
"validity": "VALID"
}
Time claims (nbf, exp, iat) are converted from epoch seconds to ISO-8601 timestamps.
The stream re-emits automatically when the token transitions between validity states (IMMATURE -> VALID -> EXPIRED).
Example:
policy "require valid jwt"
permit
<jwt.token>.valid;
Example with claims:
policy "admin access"
permit action == "admin:action";
"admin" in <jwt.token>.payload.roles;