Fehlermeldung
Jwks doesn't have key to match kid or alg from Jwt
Auch ausgegeben als
- Jwt verification fails
- Jwks remote fetch is failed
Body der 401-Antwort; der Header `WWW-Authenticate` enthält `error="invalid_token"`. Ein Provider, dessen `remote_jwks` sich nicht abrufen lässt, antwortet mit „Jwks remote fetch is failed“.
Envoy / Istio — envoy.filters.http.jwt_authn (401 response body; Istio RequestAuthentication)
Was der Fehler bedeutet
Der Filter `jwt_authn` von Envoy (den auch `RequestAuthentication` in Istio nutzt) hat im JWKS des Providers nach einem Schlüssel mit dem `kid` des Tokens und einem zum `alg` passenden Typ gesucht und keinen gefunden. Deshalb hat er mit 401 und diesem Text als Body geantwortet. Die Signatur wurde nie geprüft. Existiert ein passender Schlüssel, schlägt aber die Signaturprüfung fehl, lautet der Body stattdessen „Jwt verification fails“.
Warum der Fehler auftritt
Der Aussteller hat Schlüssel rotiert, und der Cache von Envoy ist älter
häufig`remote_jwks` wird für die Dauer von `cache_duration` zwischengespeichert (standardmäßig 5 Minuten). Tokens, die mit einem Schlüssel signiert sind, der erst nach dem letzten Abruf veröffentlicht wurde, schlagen fehl, bis sich der Cache aktualisiert.
Eine eingebettete oder lokale JWKS-Kopie
häufig`local_jwks` (oder das eingebettete `jwks:` in Istio) ist eine Momentaufnahme. Von neuen Schlüsseln erfährt es nie; jede Rotation lässt die Authentifizierung scheitern, bis die Konfiguration aktualisiert ist.
Der Schlüssel mit diesem kid hat einen anderen Typ
gelegentlichDas JWKS enthält den `kid`, aber als RSA-Schlüssel, während das Token ES256 verwendet (oder der `alg` des JWK weicht ab). Envoy verlangt, dass beides übereinstimmt.
Das Token stammt von einem anderen Aussteller
gelegentlichBei einem Provider ohne eng gefassten Abgleich auf `issuer` oder bei einer Anfrage mit einem Token eines anderen Identity Providers wird gegen den falschen Schlüsselsatz geprüft.
So behebst du den Fehler
- 1.
JWKS beim Aussteller abrufen
Verwende `remote_jwks` mit einer sinnvollen `cache_duration` und asynchronem Abruf, damit die Schlüssel vorliegen, bevor Tokens sie verwenden.
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.
In Istio auf jwksUri verweisen
Istiod ruft die Schlüssel ab und verteilt sie; ein eingebetteter Wert für `jwks` muss bei jeder Rotation von Hand aktualisiert werden.
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