Exposing JWKS from Apigee

OK, let's address a common misunderstanding.

Some people think that verifying JWTs requires a JWKS endpoint. This isn't true.

What's a JWK? There's a standard, RFC 7517, which describes how to serialize keys.

A JWKS (aka JSON Web Key Set) looks like this:

{
  "keys": [
    {"kty":"EC","crv":"P-256","kid":"2775c10b","x":"j5J5MsLy8KSXzEg6iDccIefx7DpXegiMmKkn6vkHmFw","y":"Sy0ImntHK0NBn0GnPw1DKd1wbpdMGyelvQBmN2ZP0Bs"},
    {"kty":"RSA","e":"AQAB","use":"sig","kid":"5601c05a","n":"gunSksQIlGfpul5q_hmwRtRor1E6eYRT9XTS-_UhZE0yO4lv0iZY5BnElzjmsuBa1bkjNBKyfASaa5_fj71eYwbz-O3iltfRmQ9wm4X_jWTtRL4xE6hydDR7o1CS7_rNdKcKjD88rhcNQmhxDZarVVSH7OYcndGgisLolo2w6lk3SN_j55AqzF2O4DGDyX-zXvv4DcEVSsprsizteZXxMGJoVKGsEx-kxoAn1OUB4CnkorWwqOiJ_RSHpd6X8fhRoWG_wEwmnd-0FFQmn3sNaR2CFmR9WHYhuDEj1VeKCMmZ_Xjh-lB2EMpyUNDug0c7tuo2EWkYxkBRJmrkrsCy5w"}
  ]
}

Each item in the "keys" array identifies (in this case) a public key. Because these keys are "public", they can be shared freely.

When verifying a signature on a JWT, the verifying system must have a public key. ONE WAY for the system to obtain the public key is to download the key from a public JWKS endpoint.

The verifying app or system can perform an HTTP GET to retrieve the JWKS payload from the well-known endpoint, and then it can select one of the keys in the retrieved list, to and then use that key to verify the JWT signature.

But a verifying system can retrieve public keys from other sources. For example the public key might be hard-coded within the system. Or provided in some configuration available to the verifier.

The point is, It is possible to use a JWKS to verify a JWT, whether you do the verification within Apigee, or using some other tool or technology. But a JWKS is not required. This is true if you do the verification in Apigee, or if you use some other tool, platform, or technology. To verify a signed JWT, you need a public key. JWKS is a handy way of publishing a list of public keys; each key can be distinguished by a unique key identifier known as a `kid`. A JWKS is sufficient but not necessary.

Normally the verify selects the correct key from the list in the JWKS by matching the kid; the JWT that will be verified includes a `kid` value in the header, and the verifying app just selects the key from the JWKS with the matching kid. Easy.

----

OK, with that all out of the way....

Apigee does not include builtin management for .JWKS content.

But it's not difficult to build this yourself. I propduced an example shows how you might use Apigee to generate JWT signed with RSA keys, and also publish a .jwks endpoint containing public keys, which allows external clients to verify the JWT.

The example API Proxy:

  • generates JWT signed with RS256
  • exposes a JWKS endpoint to allow external systems to verify the JWT

This example uses a nodejs tool to generate the .jwks content itself and load it into the Apigee KVM, where it can be retrieved by the proxy at runtime.

Find it here: https://github.com/DinoChiesa/Apigee-JWT-with-JWKS

and here's a screencast walkthrough.

Comments
umars
Bronze 1
Bronze 1

@dchiesa1  Hi, Is there an equivalent way to provision credentials on apigee x? or we have to use environment specific properties resource file option? 

Version history
Last update:
‎11-19-2019 09:07 AM
Updated by: