Kong / kong

🦍 The Cloud-Native API Gateway and AI Gateway.
https://konghq.com/install/#kong-community
Apache License 2.0
38.4k stars 4.76k forks source link

Handling two JWT signing keys for same iss #13089

Closed codingwwws closed 6 days ago

codingwwws commented 1 month ago

Is there an existing issue for this?

Kong version ($ kong version)

Kong 3.4.2

Current Behavior

I am using jwt plugin https://docs.konghq.com/hub/kong-inc/jwt/?_ga=2.53180716.589797142.1716798760-147226938.1680633234 and I am in a dbless mode with Kong ingress controller 2.12.3 using the Kongconsumer resources and an associated secret holding the public key of JWT signing key.

Basically, I have a situation that I am getting requests with an incoming JWT that are signed by jwtkey1 by the auth server. I have a Kongconsumer for the iss and Kong is trusting the token.

However, the authentication server is now deciding to rotate the signing key (every few weeks). So from now the tokens are signed by jwtkey2 ! However everything else in the token is the same including iss value (which I believe is the key and has to be unique for the Kongconsumer). Ideally, the previous tokens signed by jwtkey1 still need to be able to authenticate in Kong until they expire. However now the new tokens signed by jwtkey2 are also coming in and need to authenticate with Kong.

Currently though there is a limitation, I can’t even make a Kongconsumer which has a secret with the same iss. It won’t trust one of the signing keys (or in case of Kong 3.4.2 that I have tested, ingress controller will just simply not accept the same iss key value for two Kongconsumers and fail with:

level=error msg=“could not update kong admin” error=“performing update for http://127.0.0.1:8001/ failed: failed posting new config to /config: got status code 400” subsystem=dataplane-synchronizer
level=error msg=“failed parsing resource errors” error=“could not unmarshal config error: json: cannot unmarshal object into Go struct field ConfigError.flattened_errors of type sendconfig.FlatEntityError” update_strategy=InMemory url=“http://127.0.0.1:8001/”

How can I handle this situation? Trust two signing keys for tokens that has the same iss ?

Expected Behavior

Be able to make the separate Kongconsumers with the same iss but different token signing key.

Steps To Reproduce

  1. In Kubernetes Kong ingress controller 2.12.3,
  2. Add ingress, Service, and jwt plugin with added Kongconsumer and associated credentials secret (Using token keys info from an auth server) so kong validates the incoming token in the requests. The token
  3. Make the auth server to rotate the signing key
  4. Try making another Kongconsumer with the credentials secret using the new token key info
  5. The Ingress controller should now start failing POST to /config . failed posting new config to /config: got status code 400" subsystem=dataplane-synchronize

Anything else?

No response

StarlightIbuki commented 1 month ago

However, the authentication server is now deciding to rotate the signing key (every few weeks). So from now the tokens are signed by jwtkey2 !

Could you elaborate on this? key is supposed to be used to identify a JWT credential, not a consumer, and a rotated key should have a different key claim. @bungle Please correct me if I made it wrong.

codingwwws commented 4 weeks ago

@StarlightIbuki From what I understand and tested, the key is matched with the iss of the incoming JWT. Problem is that the JWT issuer sets the iss field to their URL. The iss doesn't change when their signing token key set is rotated. I need to trust both the previous token key set used to sign tokens as well as their new one, however the JWT plugin wants a unique key (which is the iss and not in my control)

If I provide both token key sets, it seems Kong plugin doesn't validate against both the old and new token key sets that has the same key (matches the iss of JWT). Just the first one it sees is used in Kong plugin. So it assumes key is unique and iss matches with it. I have made both token keys in secrets under the credentials field in the KongConsumer similar to example:

image
StarlightIbuki commented 4 weeks ago

@codingwwws I'm not sure I fully understand your deployment but you seem to use a 3rd-party service to issue keys and clients rely on it to generate JWTs. Maybe you can find a claim in the JWT to identify the key used to sign. Set the key_claim_name and use the value as the key to let Kong know the right way to identify a key.

github-actions[bot] commented 1 week ago

This issue is marked as stale because it has been open for 14 days with no activity.

github-actions[bot] commented 6 days ago

Dear contributor,

We are automatically closing this issue because it has not seen any activity for three weeks. We're sorry that your issue could not be resolved. If any new information comes up that could help resolving it, please feel free to reopen it.

Your contribution is greatly appreciated!

Please have a look our pledge to the community for more information.

Sincerely, Your Kong Gateway team