本文へスキップ
ecdsa.com
Envoy / IstioJWKS と鍵のディスカバリ

エラーメッセージ

Jwks doesn't have key to match kid or alg from Jwt

別の表記

  • Jwt verification fails
  • Jwks remote fetch is failed

401 のレスポンス本文です。`WWW-Authenticate` ヘッダーには `error="invalid_token"` が含まれます。`remote_jwks` を取得できないプロバイダーは「Jwks remote fetch is failed」と応答します。

Envoy / Istio — envoy.filters.http.jwt_authn (401 response body; Istio RequestAuthentication)

このエラーの意味

Envoy の `jwt_authn` フィルター(Istio の `RequestAuthentication` でも使われます)は、トークンの `kid` を持ち、その `alg` に合う種類の鍵をプロバイダーの JWKS から探しましたが、見つからなかったため、このテキストを本文として 401 を返しました。署名は一度も検証されていません。一致する鍵はあるものの署名を検証できない場合は、本文が「Jwt verification fails」になります。

発生する理由

修正方法

  1. 1.

    発行者から JWKS を取得する

    適切な `cache_duration` と非同期取得を設定して `remote_jwks` を使い、トークンが鍵を使う前に鍵がそろっているようにしてください。

    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. 2.

    Istio では jwksUri を指定する

    Istiod が鍵を取得して配布します。インラインの `jwks` の値は、ローテーションのたびに手作業で更新しなければなりません。

    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

関連するエラー

署名エラーデータベースをすべて見る