Feedback on Caching JWKS for JWT Verification in Ruby

Hello Auth0 Community,

I have implemented JWT verification in my application by following the Auth0 documentation. After further reading on how to locate JSON Web Key Sets, I decided to enhance the efficiency of the process by implementing caching. This way, I avoid performing an HTTP request to Auth0 for each token verification.

Here’s the code snippet I’m using for caching the JWKS:

# frozen_string_literal: true

require "net/http"
require "uri"

class JsonWebToken
  TOKEN_ISSUER = ENV.fetch("AUTH0_TOKEN_ISSUER").chomp("/").concat("/")
  AUDIENCE = ENV.fetch("AUTH0_AUDIENCE")
  JWKS_CACHE_EXPIRE_IN = 2.hours

  def self.verify(token, retrying: false)
    JWT.decode(
      token,
      nil,
      true,  # Verify the signature of this token
      algorithms: "RS256",
      iss: TOKEN_ISSUER,
      verify_iss: true,
      aud: AUDIENCE,
      verify_aud: true
    ) do |header|
      jwks_hash[header["kid"]]
    end
  rescue JWT::DecodeError => e
    raise if retrying

    Rails.cache.delete("jwks_keys")
    verify(token, retrying: true)
  end

  def self.jwks_hash(force_update = false)
    Rails.cache.fetch("jwks_keys", force: force_update, expires_in: JWKS_CACHE_EXPIRE_IN) do
      jwks_raw = Net::HTTP.get URI("#{TOKEN_ISSUER}.well-known/jwks.json")
      jwks_keys = Array(JSON.parse(jwks_raw)["keys"])
      jwks_keys.map do |key|
        [
          key["kid"],
          OpenSSL::X509::Certificate.new(
            Base64.decode64(key["x5c"].first)
          ).public_key
        ]
      end.to_h
    end
  end
end

I would greatly appreciate any feedback on this implementation:

  1. Is this implementation correct and secure according to best practices?
  2. What is the recommended expiration time for caching the JWKS?
  3. Are there any other recommendations or best practices I might have missed?

Thank you for your time and assistance!

Hey @raphael.egeley welcome to the community!

Great Idea! Overall, I think your approach is good - There isn’t a recommended time to cache tokens. The following post expands on caching JWKs and is still useful despite being a few years old.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.