---
title: JwtValidationFilter
description: Validates an unsigned, signed, encrypted, or signed and encrypted JWT. The order of signing and encryption isn't important; a JWT can be signed and then encrypted, or encrypted and then signed.
component: pinggateway
version: 2026
page_id: pinggateway:reference:JwtValidationFilter
canonical_url: https://docs.pingidentity.com/pinggateway/2026/reference/JwtValidationFilter.html
revdate: 2025-11-25
section_ids:
  JwtValidationFilter-usage: Usage
  JwtValidationFilter-properties: Properties
  JwtValidationFilter-jwt: jwt
  JwtValidationFilter-verificationSecretId: verificationSecretId
  JwtValidationFilter-decryptionSecretId: decryptionSecretId
  JwtValidationFilter-secretsProvider: secretsProvider
  JwtValidationFilter-skewAllowance: skewAllowance
  JwtValidationFilter-customizer: customizer
  JwtValidationFilter-failureHandler: failureHandler
  JwtValidationFilter-example: Example
  JwtValidationFilter-moreinfo: More information
---

# JwtValidationFilter

Validates an unsigned, signed, encrypted, or signed and encrypted JWT. The order of signing and encryption isn't important; a JWT can be signed and then encrypted, or encrypted and then signed.

If the JWT is validated, the request continues down the chain and data is provided in the [JwtValidationContext](JwtValidationContext.html).

If the JWT isn't validated, data is provided in the [JwtValidationErrorContext](JwtValidationErrorContext.html). If a failure handler is configured, the request passes to the failure handler. Otherwise, an HTTP 403 Forbidden is returned.

## Usage

```none
{
  "name": string,
  "type": "JwtValidationFilter",
  "config": {
    "jwt": runtime expression<string>,
    "verificationSecretId": configuration expression<secret-id>,
    "decryptionSecretId": configuration expression<secret-id>,
    "secretsProvider": SecretsProvider reference,
    "skewAllowance": configuration expression<duration>,
    "customizer": JwtValidatorCustomizer reference,
    "failureHandler": Handler reference
  }
}
```

## Properties

### jwt

`"jwt"`: *runtime expression<[string](preface.html#definition-string)>, required*

The value of the JWT in the request. Cannot be null.

### verificationSecretId

`"verificationSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required to verify the signature of signed tokens*

The secret ID used for the secret to verify the signature of signed tokens.

This secret ID must point to a [CryptoKey](../security-guide/keys.html#secret-types).

If configured, the token must be signed. If not configured, PingGateway doesn't verify the signature.

Learn more in [Validate the signature of signed tokens](../security-guide/keys.html#secret-valid-signature).

Learn how each type of secret store resolves named secrets in [Secrets](secrets.html).

### decryptionSecretId

`"decryptionSecretId"`: *configuration expression<[secret-id](preface.html#definition-secretid)>, required if AM secures access tokens with encryption*

The secret ID for the secret to verify the encryption of tokens.

This secret ID must point to a [CryptoKey](../security-guide/keys.html#secret-types).

If configured, the token must be encrypted. If not configured, PingGateway doesn't verify the encryption.

Learn how each type of secret store resolves named secrets in [Secrets](secrets.html).

### secretsProvider

`"secretsProvider"`: *SecretsProvider [reference](preface.html#definition-reference), required*

The [SecretsProvider](SecretsProvider.html) to query for passwords and cryptographic keys.

### skewAllowance

`"skewAllowance"`: *configuration expression<[duration](preface.html#definition-duration)>, optional*

The duration to add to the validity period of a JWT to allow for clock skew between different servers.

A `skewAllowance` of 2 minutes affects the validity period as follows:

* A JWT with an `iat` of 12:00 is valid from 11:58 on the PingGateway clock.

* A JWT with an `exp` 13:00 is expired after 13:02 on the PingGateway clock.

Default: To support a zero-trust policy, the default skew allowance is `zero`.

### customizer

`"customizer"`: *JwtValidatorCustomizer [reference](preface.html#definition-reference), optional*

A set of validation constraints for JWT claims and sub-claims. These constraints are in addition to internally defined constraints, such as `aud`, `iss`, `exp`, and `iat`. If a claim isn't validated against a constraint, the JWT isn't validated.

The customizer doesn't override existing constraints. Defining a new constraint on an already constrained claim has an impact only if the new constraint is more restrictive.

JwtValidatorCustomizer provides a ScriptableJwtValidatorCustomizer to enrich a `builder` object by using its methods. Get more information about:

* The `builder` object in [Available Objects](Scripts.html#Scripts-availableob).

* Transformer methods to enrich the builder object in [org.forgerock.openig.util.JsonValues](../_attachments/apidocs/org/forgerock/openig/util/JsonValues.html).

* Constraints in [org.forgerock.openig.tools.jwt.validation.Constraints](../_attachments/apidocs/org/forgerock/openig/tools/jwt/validation/Constraints.html).

* Other properties for ScriptableJwtValidatorCustomizer in [PingGateway scripts](Scripts.html).

The following examples verify claims:

* Check the value of the claim `greaterThan5` is greater than 5

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [
      "builder.claim('/greaterThan5', JsonValue::asInteger, isGreaterThan(5))"
    ]
  }
}
```

* Check the value of the claim `sub` is `george`

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [
      "builder.claim('subname', JsonValue::asString, isEqualTo('george'))"
    ]
  }
}
```

* Check the value of the custom sub-claim is `Ping Identity`

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [
      "builder.claim('customclaim/subclaim', JsonValue::asString, isEqualTo('Ping Identity'));"
    ]
  }
}
```

* Check the values of multiple claims

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [
      "builder.claim('aud', listOf(JsonValue::asString), contains('My App'))",
      "       .claim('iat', instant(), isInThePast())",
      "       .claim('exp', instant(), isInTheFuture());",
      "builder.claim('iss', JsonValue::asString, isEqualTo('PingAM'));"
    ]
  }
}
```

* Check the value of `val1` is greater than `val2`

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [ "builder.claim('/val1', JsonValue::asInteger, isGreaterThan(claim('/val2').asInteger()))" ]
  }
}
```

* Check the value of `val1` is greater than `val2`, when both are YYYY-MM-DD dates

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [
      "Function<JsonValue, java.time.LocalDate, Exception> asDate() {",
      "  return (jsonValue) -> java.time.LocalDate.parse(jsonValue.asString());",
      "}",
      "builder.claim('claim1', asDate(), isGreaterThan(claim('claim2').as(asDate())));"
    ]
  }
}
```

* Check the claim issuer matches the regex pattern

```none
"customizer": {
  "type": "ScriptableJwtValidatorCustomizer",
  "config": {
    "type": "application/x-groovy",
    "source": [ "builder.claim('iss', JsonValue::asString, find(~/.*am\.example\.(com|org)/))" ]
  }
}
```

Default: Claims aren't validated

### failureHandler

`"failureHandler"`: *Handler [reference](preface.html#definition-reference), optional*

A [Handler](Handlers.html) to process the request on failure.

Provide an inline handler configuration object or the name of a handler object declared in the heap.

Default: PingGateway returns HTTP 403 Forbidden and stops processing the request.

## Example

You can find an example of using JwtValidationFilter in [JWT validation with PingAM](../gateway-guide/validate-jwt.html).

## More information

[org.forgerock.openig.filter.jwt.JwtValidationFilter](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationFilter.html)

[org.forgerock.openig.filter.jwt.JwtValidationContext](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationContext.html)

[org.forgerock.openig.filter.jwt.JwtValidationErrorContext](../_attachments/apidocs/org/forgerock/openig/filter/jwt/JwtValidationErrorContext.html)

[OpenID Connect Core 1.0 incorporating errata set 1](https://openid.net/specs/openid-connect-core-1_0.html)
