Improve performance of JWKS Caching Provider
pdewilde opened this issue · 4 comments
Checklist
- I agree to the terms within the Auth0 Code of Conduct.
Describe the problem you'd like to have solved
Currently jwks/CachingProvider uses a global lock within its key function:
go-jwt-middleware/jwks/provider.go
Line 129 in c83a824
This is in the hot path of every call to validate:
go-jwt-middleware/validator/validator.go
Line 183 in c83a824
This effectively serializes every http call that the middelware handles, and adds a good deal of locking overhead.
Additionally, there is no "refresh before expiry" mechanism, which mean you are guaranteed to block when the key expires after TTL minutes.
Describe the ideal solution
To avoid a global lock, you could use a sync.RWMutex
, which makes sense in the JWKS usecase where most calls to the cache will be readers. This allows multiple readers to concurrently access the critical path, and only blocks when a writer needs to update a key.
An example implementation can be found: https://github.com/sethvargo/go-cache/blob/main/ttl.go
To avoid the blocking problem, you can use a reloading chache. I'm not too familiar with the options in the go ecosystem, but in Java there is both caffine and Guava. The main idea is to reload keys asynchronously before they expire, so that you don't have to wait to refresh a hot key.
The semantics for such a cache are that a key is "stale" after some time, and stale reads return with the cached value immediately but asynchronously kick off a fetch (with additional checks that a fetch for the key isn't currently in progress). If a key does get old enough that expires, you then will have a blocking fetch.
Alternatives and current workarounds
No response
Additional context
No response
It appears that https://github.com/s12v/go-jwks may implement refreshing before expirary
Another example here: https://pkg.go.dev/github.com/lestrrat-go/jwx/v2/jwk#section-readme
Hey @pdewilde, thanks for the thorough issue! We'll review your suggestions and look to improve if the areas you've suggested.