How to solve Envoy "Jwks remote fetch is failed" error response

Emmanuel Gautier / January 29, 2023

3 min read

A way to authenticate requests to an API is to use a Bearer JWT. Those JWT may be issued from an OAuth2 or an OpenId Connect issuer. In order to validate the tokens, the public keys are needed to ensure the JWT has been generated from the known issuer and those public keys are accessible from an HTTP Endpoint so you have to configure it to fetch them automatically. If you want to make Envoy validate tokens, sometimes you may have the error Jwks remote fetch is failed. There are at least three reasons this error appears, so let's check them to fix this issue.

Check JWKS URI is right

The first obvious thing to do is to check whether the JWKS URI is good or not. I know it is very obvious but, you know, mistakes can happen. This URI should be accessible publicly through HTTPs and you should have a JWKS JSON like that:

{
  "keys": [
    {
      "kid": "...",
      "use": "sig",
      "e": "AQAB",
      "n": "...",
      "kty": "RSA",
      "alg": "RS256"
    },
    {
      "kty": "RSA",
      "kid": "...",
      "alg": "RS256",
      "use": "sig",
      "e": "AQAB",
      "n": "..."
    }
  ]
}

For the OpenId Connect provider, for instance, the JWKS URI can be the root path of the issuer with .well-known/openid-configuration. For Google Identity Platform (and Firebase) projects you should have this URI: https://securetoken.google.com/youprojectname/.well-known/openid-configuration. In the JSON response you have a property jwks_uri which contains the value of the JWKS URI, URI you must configure in Envoy.

Check if you can use HTTPs

The JWKS URI should not be accessible through HTTP without the secure layer (HTTPs) for security reasons. So, another potential issue is that the cluster has no transport socket configured. Check if the cluster Envoy configuration has those lines for TLS Transport Socket:

    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        sni: issuerdomainname.com

If you copied the lines above, change the sni property with the domain name configured for the cluster.

IPv6 or IPv4

The JWKS URI may be accessible with IPv6 which is great but if your cluster has no IPv6 connectivity, Envoy will only try with IPv6 and fail to fetch JWKS. If you are in this scenario, you should put the configuration dns_lookup_family to V4_ONLY. More information in the Envoy configuration documentation.

    dns_lookup_family: V4_ONLY

Full Example

Here is a full example of the cluster configured for fetching Google Identity Platform JWKS:

  clusters:
  - name: service_googleapis_com
    connect_timeout: 30s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_googleapis_com
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.googleapis.com
                port_value: 443
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        sni: www.googleapis.com

Hope those solutions help you to solve your error.

Consulting

If you're seeking solutions to a problem or need expert advice, I'm here to help! Don't hesitate to book a call with me for a consulting session. Let's discuss your situation and find the best solution together.

Share this post
Follow the RSS feed