Verifying JWTs with JWKS URL from the token

Hi,

I have a single-tenant application that receives requests from users containing an access token they get from AWS Cognito. I use Joken to verify the token with the help of Joken JWKS hook to fetch the public keys from a URL. The single static URL is is part of my application configuration.

Now the problem: I need to turn my application into multi-tenant, hence it will have to verify tokens from different Cognito’s user pools, which means different JWKS URLs. Instead of only one statically configured URL, each token will bring it in its “iss” claim.

The DefaultStrategyTemplate doesn’t seem to support this dynamic approach, so I’m wondering if there is an alternative or if I’ll have to code it myself. In the latter case, would it be an implementation of the JokenJwks.SignerMatchstrategy behavior or an entire Joken.Hooks?

Regards,

Roger

Neither of those.

Assuming you have the same claims in all of them except the issuer you can make a special function like handle_token or something outside the functions the macro gives you (validate_and_verify etc)…

You do need a separate Jwks Strategy for each (key) provider/link but you can re-use the same module (the one where you do use Joken.Config).

In your handle_token you grab token_config() (as provided by the macro Joken.Config), then you add the issuer claim to it based on which issuer it is and then you simply do:

config = token_config() 
# add your issuer to config
Joken.verify_and_validate(config, token, nil, nil, [
         {JokenJwks, strategy: JwksOneOfYourStrategyPickedBasedOnIss}
       ])
     end

That’s the tricky part, because the “link” is only known in runtime when verifying the token, derived from the “iss” claim, which follows this pattern:

https://cognito-idp.{region}.amazonaws.com/{userPoolId}/.well-known/jwks.json

where the userPoolId is a “random” string automatically created by Cognito when the user pool is created.

I guess I have two options:

  1. Add the list of all the possible URLs in the application’s runtime configuration and start one DefaultStrategyTemplate process for each one under my application supervisor. This is not ideal because we would be concerned about changes in the user pools in Cognito.

  2. Start DefaultStrategyTemplate process on-demand when verifying a token with an issuer that has no associated process yet. With this approach we wouldn’t need a pre-defined list of URLs but we would have to come up with some housekeeping logic to stop the strategies that are no longer valid or needed.

Is this aligned to what you have thought or I got it wrong?

I’d go with number two :slight_smile:

Or make my own variant of jwks maybe, using their code but adjusting it for being more on-demand/multiplexed.

I guess spinning it up dynamically based on iss and pruning after X hours/days with housekeeping in a genserver/supervisor is a good way too (your number two basically).

1 Like