Tyk JWT gatway log indiates different kid key than sent in JWT

Why is the Tyk log showing a different kid key than was sent in the curl Authorization header?

Sent the following JWT header, full JWT base64 is at end of this message. Below was decoded here.

Header:
{
"kid": “5717e468bceab81d1b000001939e025db68c4bc059cdee3c48874c91”,
“typ”: “JWT”,
“alg”: “HS256”
}

Data:
{
“sub”: “google-oauth2|114386168700053341693”,
“aud”: “KjPmsukutSwfo0EN03dzT95q3R0tL5Nq”,
“kid”: “5717e468bceab81d1b000001939e025db68c4bc059cdee3c48874c91”,
“iss”: “https://skillsoft-troy.auth0.com/”,
“exp”: 1461649249,
“iat”: 1461613249
}

The tyk gateway log indicates:

[Apr 25 16:46:31] WARN auth-mgr: Key not found in storage engine err=Key not found inbound-key=5717e468bceab81d1b000001b64d7ecacfbeec88a452ad886a90fd4f
[Apr 25 16:46:31] ERROR Could not identify a policy to apply to this token!

curl with full JWT:

curl -X GET --header ‘Accept: application/vnd.api+json’ --header ‘Authorization: eyJraWQiOiI1NzE3ZTQ2OGJjZWFiODFkMWIwMDAwMDE5MzllMDI1ZGI2OGM0YmMwNTljZGVlM2M0ODg3NGM5MSIsInR5cCI6IkpXVCIsImFsZyI6IkhTMjU2In0.eyJzdWIiOiJnb29nbGUtb2F1dGgyfDExNDM4NjE2ODcwMDA1MzM0MTY5MyIsImF1ZCI6IktqUG1zdWt1dFN3Zm8wRU4wM2R6VDk1cTNSMHRMNU5xIiwia2lkIjoiNTcxN2U0NjhiY2VhYjgxZDFiMDAwMDAxOTM5ZTAyNWRiNjhjNGJjMDU5Y2RlZTNjNDg4NzRjOTEiLCJpc3MiOiJodHRwczpcL1wvc2tpbGxzb2Z0LXRyb3kuYXV0aDAuY29tXC8iLCJleHAiOjE0NjE2NDkyNDksImlhdCI6MTQ2MTYxMzI0OX0.EkWw1tyamqFDC2wW_QnaGfUCBMFnfG3C6PNlcVSSxMo’ ‘http://tyk-vbox:8080/test2/foo

Secret for proof of validation:

aEE3DXyf1stxBlu0Z-4u68_xo_RCXdQe5hJtQ56U-JyIlw37ycHjy5FP7n-Grtwe

JWT key library

The following library was used to decode the auth0 JWT, add kid header, and encode and sign the key with the same secret.

com.nimbusds nimbus-jose-jwt 4.15

Successful Auth0 and Tyk integration example here.

Because a kid usually represents a key_id - (usually an actual RSA key - such as in a JWK if your IDP are running a rotation or set of public keys), what you seem to doing is conflating the centralised JWTs with one-to-one mappings.

In one-to-one, the kid must match a token in Tyk, as in, you have a key registered in Tyk with a shared secret, it cannot be stored with the API (centralised) - this is actually a very rarely used method of JWT’s with Tyk, and not really the intended use case because it will end up rate limiting the user across kid’s, as in, any user from that kid will be rate limited the same way - which is cool if you want to rate limit the provider.

With centralised secrets (JWT shared secret stored with the api), Tyk creates internal representations of tokens that are tied to the identity of the JWT holder, i.e. the sub or email claim. This means rate limits are applied across JWTs for the same identity no matter what client they use but do not affect other users of the client. Unfortunately, to get this to work, you need to expose the policy ID you want this internal representation to use as part of the token claims so Tyk has a template to work from.

What you want is a token tied to a client ID (in the OAuth sense of client), which would be the azp claim, and you can do this with our nightlies - check the changelog in dev branch or the feature ticket in our roadmap - we just added the capability to add a key to tyk to act as a proxy for an Oauth client ID, so you don;t need to expose the policy ID but instead can just match Clients across IDPs.

I’ve set the kid and the sub to match the Dashboard : System Management : Keys ID which is 5717…4c91. I’m sending the JWT in the Authorization header. The gateway log is now spitting out the following even the the key does match exactly and the JWT is valid and verified externally. Maybe I’m entering the secret incorrectly.

[Apr 25 22:53:41] INFO Attempted JWT access with non-existent key. key=5717e468bceab81d1b000001939e025db68c4bc059cdee3c48874c91 key_present=true origin=192.168.0.2 path=/test2/foo
[Apr 25 22:53:41] ERROR Token validation error: signature is invalid

The JWT validates.

My question is why isn’t Tyk finding this or validating the signature??

In the API JWT configuration

  • what is the format of the secret - base64?
  • what does “Secret (leave blank to embed in key session)” mean?

In the Dashboard : System Management : Keys

  • what is the format of the secret - base64?

I’ve tried all kids of combinations and get the above or the following which doesn’t match what was encoded in the valid and verified JWT.

[Apr 25 22:33:47] WARN auth-mgr: Key not found in storage engine err=Key not found inbound-key=5717e468bceab81d1b000001a8b2219fab2c7873f716b6c86ea6834d
[Apr 25 22:33:47] ERROR Could not identify a policy to apply to this token!

Hi Troy, if you are doing one to one (kid to key in Tyk) then remove the secret from the API definition and add the secret to the key itself.

Depending on where the secret is stored causes Tyk to validate the token either one to one (secret is stored with the key) or centrally with a virtual token (secret stores in API definition).

RSA public keys should be PEM encoded while HMACs can be arbitrary stings. Suggest you stick with those for now.