We have used Auth0 for about 9 years in a production environment supporting thousands of users. In the past 2 weeks, we have had 2 incidences where we began hitting rate limits for JWKS.
In researching this, we have found that we have not been following best practices by caching the JWKS. We have been pulling JWKS on both the client side and our server side on each token validation (once per client session). We will obviously be addressing this.
My question is what caused us to finally hit rate limits with this bad behavior after ~9 years? Did something change in how the limits were handled or perhaps they were stated but now are actually enforced? While the above will likely fix our problem, drilling down to root cause on what caused our recent failures is important from an accountability point of view both internally and to our customers. We would appreciate any info that helps us get to that root cause. Thanks so much!
The sudden appearance of what I understand to be 429 Too Many Requests (Rate Limit) errors for your /.well-known/jwks.json endpoint would be the result of recent shift toward stricter, hard-capped rate limit enforcement combined with the gradual, compounding growth of your user base over the last 9 years. What used to be a “soft” limit or a request volume masked by the edge CDN is now strictly metered by Auth0’s modern rate limiting algorithm.
As you already noted, the fix is to implement JWKS Caching .
If you are using Node.js, the official jwks-rsa library handles this perfectly. For other languages, ensure your JWT validation library supports caching the public key.
The Best Practice Pattern:
Fetch Once: Fetch the JWKS file when your server boots up or on the very first request.
Cache it: Keep the keys in memory.
Only Refresh on Unknown kid : Your server should only reach out to /.well-known/jwks.json again if it receives a JWT with a kid (Key ID) in the header that does not match the keys currently in your cache. This indicates Auth0 has rotated the keys, and you need the new one.
Rate-Limit the Refresh (Crucial): If an attacker sends you 1,000 invalid tokens with fake kid s, you don’t want your server to make 1,000 requests to Auth0 trying to find them. Put a cooldown (e.g., “do not refresh JWKS more than once per minute”) on your cache-miss logic.
Let me know if I can help you out with anything else.