We hit some performance issues in production for our web app this week for a few different reasons. One of the low-hanging fruits was to cache the JWT verification response to reduce the calls to JWKS endpoint.
The JSON Web Key Set (JWKS) is a set of keys containing the public keys used to verify any JSON Web Token (JWT) issued by the authorization server and signed using the RS256 signing algorithm. - "About JWKS" on Auth0
We used the node-jwks-rsa
library in the Express.js app. After implementing the cache, we saw the response time of our app dropped from 65ms to less than 10ms, which was a massive improvement in performance worth celebrating.
We retrospectively wrote an integration test (which was an exception given the urgent circumstances) based on this useful blog post on Mocking JWT and Auth0 by Carter Bancroft.
It turned out that the library also caches error response. If the first call to the JWKS endpoint fails, the error response will also be cached. This means that our users won’t be able to use our app until the cache invalidates, even though it could have just been a transient error.
To validate that it was not a layer 8 problem of writing weird test code, we also ran the app locally and made the JWKS endpoint to return success and error every other time.
According to Caching anti-pattern by Google Cloud Apigee, “it is not advisable to cache error responses without considerable thought on the adverse implications”.