JWT JWKs error "Key must be PEM encoded PKCS1 or PKCS8 private key"

For you, or for anyone else who has also tried their hand at getting this to work - you are not crazy. It does not work - at least not with a standards-compliant jwks.json file

I have also been experimenting with the JWT Authorization configuration, trying to get an API to accept the Access Token issued by an OIDC Provider (in my case is it also happens to be Auth0), and finding the same error you do.

From the logs, I can also see “Failed to decode JWT to RSA type”. Using this breadcrumb, I started to hunt and peck through the codebase and found:

  1. If you put a URL in the field for “Public Key” in the Dashboard (equivalent, I believe, to putting the base64-encoded version of the URL into the “jwt_source” field in the API definition), Tyk will fetch the jwks.json file specified
  2. It unpacks the json of the jwks
  3. It grabs the first value in x5c and uses it as the cert
  4. It then tries to decode the value as a PEM file

The issue with 4 is that the specification of x5c is to be base64-encoded DER and not base64-encoded PEM, like this code wants.

This is known to be non-standard with the recommendation being to use OpenID Connect as an auth mechanism.

The issue with that is that the OpenID Connect mechanism expects users (or OAuth2 clients, whatever the case is) to use ID Tokens. This, however, is not recommended because the Access Token is supposed to be used for accessing APIs on the Resource Server. That is, standards-compliant clients will be expecting to send the Access Token, and those will get rejected (unless, of course, you could tweak the aud parameter injected into the Access Token; this is not possible with Auth0).

If you have the time and the inclination to do so, one way you could get around this issue would be to have a custom server that could translate the x5c parameter from DER to PEM on the fly (i.e. GET https://tykx5ctranslator.com/?jwksSource=https%3A%2F%2Fmytenant.auth0.com%2F.well-known%2Fjwks.json )
I don’t have either, so I’m probably going to go skipping the use of a JWKs URL, and instead specifying the PEM file for each API definition.

Either that or replacing Tyk in our stack.

3 Likes