-
Notifications
You must be signed in to change notification settings - Fork 73
Support updating JWKSet #153
Comments
This could be quite useful feature in case you chose to use authentication through JWT issued by Firebase Auth or Auth0's, since they rotate their JWKs periodically. |
Makes a lot of sense. I'll make the changes. |
@lachezar I'm only familiar with AWS Cognito. Do Firebase and Auth0 have a URL with the JWK set encoded as JSON as well? Is the URL usually public? Do you know if their cache headers state how often they rotate? If so, it might make sense to write a helper function that does all of the setup for Cognito/Firebase/Auth0 in one go. |
@jkarni yes, they have a public url with their JWK set, however they also have different formats from what I have read about the topic from Hasura's docs - https://hasura.io/docs/1.0/graphql/manual/auth/authentication/jwt.html#popular-providers-and-known-issues I have not seen any official information how often Google rotate the keys for Firebase, but from empirical tests (refreshing the endpoint https://www.googleapis.com/service_accounts/v1/jwk/[email protected] for their JWK set in the browser every now and then) it seems the key is swapped once a week. I think the refresh duration could be a configuration option in the JWKSettings and this would allow the users to work around all possible cases. |
I can offer another example and say that these are all true for Okta as well. However, on Okta you can set up different "Authorization Servers" which will sign the JWT. In other words, while the URL for the JWKs is public, it's dependent on which server you use (but I imagine that you probably wouldn't use more than one auth server in a single project?). In addition, Okta recommends caching these for a short duration:
For Okta, they also include a In short, for our projects relying on Okta, we would retrieve the JWK from a cache or by issuing a |
Thanks @erewok. AWS Cognito seems to cache for ~ 24h.
This would be the easiest to implement. On the other hand that likely adds at least 10ms per request, which is quite a lot. Since it seems most identity providers do set cache headers, a better approach would be to cache based on that. Sadly, it doesn't seem like there's any haskell http client that allows configuring a cache (but does that processing of the various cache headers automatically)! The alternative is to keep an IORef/MVar/etc with the key, which is where authentication reads from. And then either fork a thread to periodically check for updates, or check for an update every time a request comes in that is signed by a key that isn't in that ref. |
In the past, I have put them in redis with a TTL larger than the cache control header suggests and then I have always optimistically pulled from the cache while falling back to a Thanks for working on this, by the way. I experimentally tried to use Years ago, we had a reverse-proxy based on OpenResty that used this auth0-lua-nginx project to do all of this before forwarding requests upstream and that was pretty fancy and nice because each project only needed to check scope or something and no longer needed to validate the JWT. |
We have a service which periodically needs to update the set of known keys which will be used to sign requests. The simplest way I can see to allow this is to have
become
or something isomorphic to this. For our particular use case this happens frequently enough that it would be better to not have to shoot the service in the head to periodically fetch the latest keys.
The text was updated successfully, but these errors were encountered: