JWKS and JWK selection by filtering

When a JSON Web Key Set provider is configured to be used in a mapping, the keys in the set will be consulted when trying to verify a JWS or when decrypting a JWE.

Since there are potentially multiple JWKS and multiple keys per key set, reducing the number of processed keys by filtering is recommended. By doing so, only a selection of keys is processed for the verification or decryption of the given token instead of all available keys.

  • The gateway uses a 2-stage filtering process to reduce the number of processed keys:
  • Stage 1 – JWKS are filtered by their Issuer information.
  • Stage 2 – The individual keys of the selected JWKS are finally filtered according to their key properties.
  • JSON Web Key Sets (JWKS) can have two sources:
  • They can be locally configured.
  • They can be configured to be dynamically fetched from a remote source using a Service URL.

Stage 1 – JWKS issuer selection

The Issuer information is used as a restriction to reduce the number of processed JWKS per mapping. Since the issuer information is optional, selecting JWKS is based upon several options.

  1. For all referenced JWKS of a mapping:
  2. All key sets without issuer information are being selected.
  3. All key sets with issuer information that matches the iss claim of the currently processed JWT are being selected.
  4. That means key sets will not be considered if the issuer information does not match the iss claim of the processed JWT.

Example:

  1. Given a mapping has 4 providers with and without iss restrictions:
  2. Local JWKS with local_issuer_name.
  3. Local JWKS without issuer information.
  4. Remotely fetched JWKS with remote_issuer_name.
  5. Remotely fetched JWKS without issuer information.

With this set of information, 4 different types of request scenarios are possible:

  • Request where JWT iss == local_issuer_name:
  • Selected JWKS: 1 + 2 + 4
  • Request with JWT with iss == remote_issuer_name:
  • Selected JWKS: 2 + 3 + 4
  • Request with JWT without any iss:
  • Selected JWKS: 2 + 4
  • Request where JWT iss does not match any JWKS issuer:
  • Selected JWKS: 2 + 4

Stage 2 – Property selection mechanism

Using JWK properties, the key selection filter can further reduce the number of keys that have to be tried for the two JWT types JWS and JWE.

  • Keys are filtered out when:
  • The optional "use" property does not match the JWT type.
  • The optional "key_ops" does not contain the relevant value of the JWT type.
  • The optional "alg" property in its header does not match the "alg" property of the JWT.
  • The JWTs optional "kid" property in its header does not match the keys "kid" property.

The property selection mechanism only uses a limited number of properties specified for JWT.

The following table adds more detailed information about the properties and their possible values:

Property name

Description

Possible values

"use"
  • It states the intended use for the public key.
  • This property is optional.
  • "sig" – for signing or verifying
"key_ops"
  • This property is an array that can have entries of different values.
  • The array values define the key operations that may be performed with that property.
  • This property is optional.

  • Only two values are relevant:
  • "verify" – to verify JWS'
  • "decrypt" – to decrypt JWEs
"alg"
  • This property specifies the cryptographical algorithm the JWT is intended to be used with.
  • This property is optional.
  • JWE/JWS and JWKs must use the same "alg"-value.
  • JWEs with the "alg" property "dir" require symmetric keys. In addition, the key length must match the "enc" key value of the JWE.
  • Reference lists of supported JWKS algorithms
"kid"
  • The key ID identifies the key and may be present in the JWT's header.
  • This property is optional.
  • JWE/JWS and JWKs must have the same "kid".

JWKS format example

A JWKS is a set of JWK and has the following format:

{ 
  "keys": <array_of_jwk> 
}

Here is an example with two JWK entries:

Show moreShow less
{ 
  "keys": [ 
    { 
      "kty": "RSA", 
      "n": "AJdfpzpkSaMpiyKgsqbr9n1jpnA12vZy8NntcQgxg-oh8N2Lhmdt0ks3i08s4WC7tod6irhXBwdp5QHyRZDODbIzWtJMOk94vZYp9AKJNpoeqdmbe0zLISmzBanRYRNZhMBkRCQCqob2i3urm-RE09HLTT_wvMxLNFuxwTl_gF3hTK4wcjOLkAky8cDbu0NX[...]", 
      "e": "AQAB", 
      "kid": "iPz_o1_uG8p-RmrpR-MX3dO9lDvwMPjmZ-WEWvLn8QM" 
    }, 
    { 
      "kty": "EC", 
      "x": "APWNl5usaFe3K3O1tQh3bwlQBKgHPuSHZ9O9NvK7uyK2", 
      "y": "HwCd34E8zm0hjnT0c71gBmHv--ABAjFDKBu4dI2-o-w", 
      "crv": "P-256", 
      "kid": "NqFC-b4dDXt3Tmah70rYEkn8JpuPcOS19avwqyRQgqA", 
      "alg": "ES256" 
    } 
  ] 
}