JWT validation
Extensions for applying the protection:
x-42c-jwt-validation_0.1
x-42c-jwt-validation-ec_0.1
x-42c-jwt-validation-hmac_0.1
x-42c-jwt-validation-rsa_0.1
x-42c-jwt-validation_0.2
x-42c-jwt-validation-ec_0.2
x-42c-jwt-validation-hmac_0.2
x-42c-jwt-validation-rsa_0.2
x-42c-jwt-validation_0.3
x-42c-jwt-validation-ec_0.3
x-42c-jwt-validation-hmac_0.3
x-42c-jwt-validation-rsa_0.3
The numbers at the end of the extension denote the version of the protection: for example, x-42c-jwt-validation_0.1
applies the version 0.1 of the protection, x-42c-jwt-validation_0.2
the version 0.2, and so forth.
You apply protections to your API as strategies by using the x-42c
security extensions, either locally to specific paths, operations, responses, or HTTP status codes, or alternatively to all incoming requests or outgoing responses. For more details, see Protections and security extensions.
Description
JSON Web Tokens (JWT) tokens are the primary format of tokens used for API authentication. In most cases, the tokens used are signed but not encrypted. Attackers can try to break into your system by intercepting and reusing, modifying, or even creating a token of their own and relying on the backend improperly validating the token. This protection externalizes JWT validation checks and adds an additional layer of protection against JWT attacks.
You can apply this protection to your OpenAPI definition in two ways:
- Use the extension x-42c-jwt-validation and specify the algorithms API Firewall can use to validate the JWT regardless of which algorithm the token is signed with.
- Use one of the following extensions to automatically validate the JWT against a specific algorithm family (all algorithms in the family are allowed):
- x-42c-jwt-validation-ec: The JWT is validated against the Elliptic Curve algorithm family (ES256, ES384, and ES512).
- x-42c-jwt-validation-hmac: The JWT is validated against the Keyed-hash Message Authentication Code algorithm family (HS256, HS384, and HS512).
- x-42c-jwt-validation-rsa: The JWT is validated against the RSA algorithm family (RS256, RS384, RS512, PS256, PS384, and PS512).
This way, you can choose the level of control and definition that you want to use.
Direction
This protection applies only to incoming requests, not outgoing responses. The JWT must be passed in a HTTP header and in the format of JWS Compact Serialization. You can specify the name of validated header with the parameter header.name
.
JWT header and claims validation process
API Firewall performs the JWT header and claims validation as follows:
- Check if the header defined in the parameter
header.name
is included in the request. -
Check if the JWT format corresponds to the pattern of JWS Compact Serialization. The regular expression used is
^([0-9a-zA-Z\-=_]{20,})\.([0-9a-zA-Z\-_=]{3,})\.([0-9a-zA-Z\-_=]*)$
. - Check that the algorithm (field
alg
) in the key structure definition (JWK) matches the fieldalg
in the JOSE header of the JWT. -
Check that the key type can be used to validate the JWT token. The value of the field
kty
must correspond to thealg
fields in both JWK and JOSE header. - Check that the field
alg
is present in the JOSE header, its value matches authorized algorithms, and the signing algorithm is notNONE
. - Check the claims of the payload. If no claims are present in the payload, this step is skipped.
- The claim
nbf
must be before the current time. -
The claim
exp
must be after the current time. -
The claim
iat
corresponds to the token lifetime. Theiat
value plus the value of thelifetime
parameter defined for the protection must not exceed the value of the claimexp
. -
The claim
jti
must not be present in the API Firewall cache. This claim protects against replay attack. The claimjti
is stored in the API Firewall cache until thejti.timeout
of the protection expires.API Firewall ignores the
jti
claim if you use the_0.2
extensions to apply the newer version of the JWT validation protection. However, the value of the claim is still validated against the schema for the payload before it is passed on to downstream services, such as the authorization server.
- The claim
- Check the message integrity with a cryptographic signature validation.
If any of the checks fail, the protection blocks the request.
JWK configuration
Because API Firewall runs in a container, like a Kubernetes pod, you can configure the JWK as a secret and pass it to API Firewall as an environment variable.
The JWK must contain at least the following fields:
kty
: The key type. The value must beEC
,RSA
, oroct
.alg
: The algorithm of the key.
Other fields are possible and strongly depend on the used key type. For more details, see RFC 7517.
The following is an example of the key configuration in Kubernetes (angle brackets indicate placeholders):
-
Create the JWK environment file
<my-jwk.env>
:<JWK-ENV-VAR-NAME>={"kty": "oct", "alg": "HS256", "k": "b3dhc3Bicm9rZW53ZWJhcHBz"}
- Run the following to create the Kubernetes secret:
kubectl create secret generic <my-jwk-secret-name> --from-env-file=/path/to/<my-jwk.env> --namespace=<my-k8s-namespace>
- Add the environment variable for the JWK to the deployment file of your API Firewall deployment, under the section
/spec/template/spec/container/<container name>/env
:env: - name: <JWK-ENV-VAR-NAME> valueFrom: secretKeyRef: name: <my-jwk-secret-name> key: <JWK-ENV-VAR-NAME>
When you redeploy the updated API Firewall deployment, the environment variable is passed to API Firewall and this protection can access it through the parameter jwk.envvar
.
You can pass the public key required to validate the signature inside an environment variable, or retrieve it dynamically using the parameter jwks.uri
if applying the protection with _0.2
extensions. See Parameters.
Parameters
You can configure the following parameters for the different versions of the protection:
Parameter name | Description | Version |
---|---|---|
header.name
|
Required. The name of the HTTP header that contains the JWT. | All |
authorized.algorithms
|
Required for x-42c-jwt-validation . An array of the algorithms API Firewall must use to validate the JWT.You cannot mix algorithms from different algorithm families (for example, |
All |
jwk.envvar
|
The environment variable that contains the JSON Web Key (JWK) token that API Firewall can access. The environment variable is set as a secret (for example, a Kubernetes secret) and declared in the API Firewall deployment properties (see JWK configuration). The default value is JWK . This parameter is optional. |
All |
forward.jwt
|
If set to true (default), the JWT is forwarded to the backend service, otherwise it is removed from the message. This parameter is optional. |
All |
lifetime
|
Token lifetime (in seconds). You can use this parameter to specify the maximum lifetime of the JWT. For this parameter to have effect, the claim iat must be present in the payload. The default value is 5 . This parameter is optional. |
All |
drift
|
Drift time (in seconds) to allow a small leeway in case there is clock skew between the client and API Firewall. This parameter is used when checking claims dealing with time, such as like nbf and exp . The default value is 10 . This parameter is optional. |
All |
jti.timeout
|
Timeout value (in seconds) to protect the API backend from replay attacks. For this parameter to have effect, the claim jti must be present in the payload. The jti value is removed from the cache after the timeout expires. The default value is 86400 (one day). This parameter is optional.
Because the API Firewall instance stores all counters in its memory, if the instance is restarted, all values in the cache are lost. |
jti claim is ignored in _0.2 |
allow.basic.value
|
If set to true , the value of the authorization header is enforced to start with Basic or Digest token, other tokens are rejected. This can be useful if your API can accept both Basic or Bearer token depending on client, and it allows JWT validation to proceed if the authentication is passed. The default value is false . This parameter is optional. |
_0.2 only
|
jwk.cache.timeout
|
The value (in seconds) for how long the JWK retrieved from the JWKS URI is cached. The allowed timeout range is 60 — 28800 (from 1 minute to 8 hours). The default value is 3600 . This parameter is optional. |
_0.2 only
|
jwks.uri
|
The URI of JWKset (for example, https://login.microsoftonline.com/common/discovery/v2.0/keys ). This parameter is optional: if JWKS URI is not provided, the policy looks for an environment variable (defaults to JWK ) that contains the JWK used to validate the signature. |
_0.2 only
|
jwks.proxy
|
The host:port of the forward proxy that API Firewall must connect through using the HTTP CONNECT method to reach the JWKS endpoint. This parameter is required if traffic to the JWKS endpoint should go through a forward proxy.
|
_0.3 only |
API Firewall ignores the jti
claim if you use the _0.2
extensions to apply the newer version of the JWT validation protection. However, the value of the claim is still validated against the schema for the payload before it is passed on to downstream services, such as the authorization server.
Examples
x-42c-jwt-validation
Versions:
x-42c-jwt-validation_0.1
x-42c-jwt-validation_0.2
x-42c-jwt-validation_0.3
If you apply the protection using the protection name jwt-validation_<version>
, you can specify an array of algorithms in the protection parameter authorized.algorithms
. API Firewall uses the specified algorithms (and only them) to validate JWT headers and claim regardless of what algorithms they use.
/api/user/info: get: x-42c-local-strategy: x-42c-strategy: protections: - x-42c-jwt-validation_0.1: header.name: x-access-token jwk.envvar: JWK_PUBLIC_RSA_KEY authorized.algorithms: [RS256, RS384] # ...
x-42c-jwt-validation-ec
Versions:
x-42c-jwt-validation-ec_0.1
x-42c-jwt-validation-ec_0.2
x-42c-jwt-validation-ec_0.3
If you apply the protection using the protection name x-42c-jwt-validation-ec_<version>
, API Firewall automatically uses only the algorithms ES256, ES384, or ES512 of the Elliptic Curve family to validate the JWT headers and claims.
The protection also checks that the curve if the field crv
of the JWK matches the curve of the algorithm set in the field alg
:
- Curve P-256 for ES256
- Curve P-384 for ES384
- Curve P-512 for ES512
For more details, see RFC 7517 and RFC 7518.
/api/user/info: get: x-42c-local-strategy: x-42c-strategy: protections: - x-42c-jwt-validation-ec_0.1: header.name: x-access-token jwk.envvar: JWK_PUBLIC_EC_KEY # ...
x-42c-jwt-validation-hmac
Versions:
x-42c-jwt-validation-hmac_0.1
x-42c-jwt-validation-hmac_0.2
x-42c-jwt-validation-hmac_0.3
If you apply the protection using the protection name x-42c-jwt-validation-hmac_<version>
, API Firewall automatically uses only the algorithms HS256, HS384, or HS512 of the HMAC algorithm family to validate the JWT headers and claims.
/api/user/info: get: x-42c-local-strategy: x-42c-strategy: protections: - x-42c-jwt-validation-hmac_0.1: header.name: x-access-token # ...
x-42c-jwt-validation-rsa
Versions:
x-42c-jwt-validation-rsa_0.1
x-42c-jwt-validation-rsa_0.2
x-42c-jwt-validation-rsa_0.3
If you apply the protection using the protection name x-42c-jwt-validation-rsa_<version>
, API Firewall automatically uses only the algorithms of the RSA algorithm family to validate the JWT headers and claims.
/api/user/info: get: x-42c-local-strategy: x-42c-strategy: protections: - x-42c-jwt-validation-rsa_0.1: header.name: x-access-token jwk.envvar: JWK_PUBLIC_RSA_KEY # ...