Mensagem de erro
Jwks doesn't have key to match kid or alg from Jwt
Também aparece como
- Jwt verification fails
- Jwks remote fetch is failed
Corpo da resposta 401; o cabeçalho `WWW-Authenticate` traz `error="invalid_token"`. Um provedor cujo `remote_jwks` não pode ser obtido responde “Jwks remote fetch is failed”.
Envoy / Istio — envoy.filters.http.jwt_authn (401 response body; Istio RequestAuthentication)
O que significa
O filtro `jwt_authn` do Envoy (usado também pelo `RequestAuthentication` do Istio) procurou no JWKS do provedor uma chave com o `kid` do token e de um tipo compatível com o `alg` dele, não encontrou nenhuma e por isso respondeu 401 com este texto no corpo. A assinatura nem chegou a ser verificada. Se houver uma chave correspondente, mas a verificação da assinatura falhar, o corpo passa a ser “Jwt verification fails”.
Por que acontece
O emissor rotacionou as chaves e o cache do Envoy é anterior à rotação
comumO `remote_jwks` fica em cache por `cache_duration` (5 minutos por padrão). Tokens assinados com uma chave publicada depois da última busca falham até o cache ser atualizado.
Uma cópia local ou embutida do JWKS
comumO `local_jwks` (ou o `jwks:` embutido do Istio) é uma cópia estática. Ele nunca fica sabendo de chaves novas; cada rotação quebra a autenticação até a configuração ser atualizada.
A chave com este kid é de outro tipo
ocasionalO JWKS tem o `kid`, mas como chave RSA, enquanto o token é ES256 (ou o `alg` da JWK diverge). O Envoy exige que os dois correspondam.
O token pertence a outro emissor
ocasionalQuando o provedor não restringe com precisão o `issuer` aceito ou a requisição traz um token de outro provedor de identidade, o token é verificado com o conjunto de chaves errado.
Como corrigir
- 1.
Buscar o JWKS no emissor
Use `remote_jwks` com um `cache_duration` razoável e busca assíncrona, para que as chaves já estejam disponíveis antes que os tokens as usem.
yaml providers: issuer_example: issuer: https://issuer.example.com audiences: ["api://orders"] remote_jwks: http_uri: uri: https://issuer.example.com/.well-known/jwks.json cluster: issuer_jwks # a cluster with TLS to the issuer timeout: 5s cache_duration: 600s async_fetch: { fast_listener: false } # prefetch, and refetch in the background - 2.
No Istio, apontar para o jwksUri
O Istiod busca e distribui as chaves; um valor `jwks` embutido precisa ser atualizado à mão a cada rotação.
yaml apiVersion: security.istio.io/v1 kind: RequestAuthentication metadata: name: orders-jwt spec: selector: matchLabels: { app: orders } jwtRules: - issuer: https://issuer.example.com jwksUri: https://issuer.example.com/.well-known/jwks.json # not an inline "jwks:" copy