Adding a JWKS endpoint to your application - rubenarakelyan/omniauth-govuk-one-login GitHub Wiki

GOV.UK One Login allows both manual entry of your public key and a JWKS endpoint to query. This public key is used to decode JWT requests sent by your application.

It is considered best practice to provide a JWKS endpoint since this allows for easier key management (including key rotation which requires multiple keys to be presented simultaneously during the process).

To add a JWKS endpoint to your application, add the following method to your authentication controller:

def jwks
  respond_to do |format|
    format.json do
      govuk_one_login_jwk = JWT::JWK.new(
        OpenSSL::PKey::RSA.new(ENV["GOVUK_ONE_LOGIN_PRIVATE_KEY"]),
        { alg: "RS256", use: "sig" },
        kid_generator: JWT::JWK::Thumbprint,
      )
      jwks = JWT::JWK::Set.new(govuk_one_login_jwk).export
      render json: jwks
    end
    format.any { render plain: "JSON requests only", status: :unsupported_media_type }
  end
end

Then, add a route:

get "/.well-known/jwks.json", to: "omniauth#jwks"

Remember to replace omniauth with the name of your controller, if different.

If you need to rotate your keys, you can create a new JWK (JWT::JWK.new) with your new key and add it to the JWKS set (JWT::JWK::Set.new). This will return both keys.

Be aware that GOV.UK One Login caches JWKS endpoint responses for up to 24 hours. Therefore, during key rotation, you must continue to encode requests using the old key for at least 24 hours after your JWKS endpoint has started responding with both keys. After this time, you may start encoding requests with your new key, and remove the old one.