使用遠端 JWKS 設定 JWT 驗證

Cloud Service Mesh 可讓您使用 Istio RequestAuthentication 自訂資源驗證 JSON Web Tokens (JWT),確保服務安全無虞。這項設定的關鍵部分是 jwksUri 欄位,用於指定 JSON Web Key Set (JWKS) 提供者的 URI。這個 JWKS 包含用於驗證傳入 JWT 的公開金鑰。

重要事項:在 Cloud Service Mesh 中,資料層 (Envoy 代理) 負責直接從 jwksUri 擷取 JWKS 金鑰。Cloud Service Mesh 控制層 (由 Traffic Director 管理) 不會發出外部呼叫來擷取這些金鑰。也就是說,所有與外部 JWKS 供應商的網路通訊,都是從工作負載的 Envoy Proxy 發出。

外部 JWKS 存取權的必要條件

如要按照本指南操作,您需要:

  • 網際網路存取機構政策:如果 jwksUri 指向外部網際網路端點,機構政策必須允許工作負載對外存取網際網路。 Google Cloud 具體來說,請確認機構政策 constraints/compute.disableInternetNetworkEndpointGroup「未強制執行」。如果啟用這項政策,系統就無法從外部 jwksUri 擷取 JWKS。

  • 已加上標籤的 Kubernetes 工作負載RequestAuthenticationAuthorizationPolicy 資源會使用 selector 來指定特定工作負載。您必須在叢集中執行工作負載 (例如 Kubernetes Deployment),並使用政策可比對的標籤。舉例來說,httpbin 範例已設定為使用 app: httpbin 標籤執行。您可以放心使用 Istio JWT 權杖指南中的設定,搭配 httpbincurl

啟用 JWKS 擷取作業的方法

您可以透過兩種主要方式設定 Cloud Service Mesh,允許 Envoy Proxy 從外部 jwksUri 擷取 JWKS 金鑰:

這是大多數正式環境情境的建議做法,且使用 MCP 的 Cloud Service Mesh 必須採用這項做法。這個方法可讓您明確控管網格與外部 JWKS 供應商的互動方式。

使用 ServiceEntry 定義外部服務

首先,您必須建立 Istio ServiceEntry,將外部 JWKS 提供者設為網格內的已知服務。這個資源可為資料層中的 Envoy 代理程式啟用 DNS 解析和適當的路由。

如果是使用 jwksUri: "https://your-auth-provider.com/.well-known/jwks.json"RequestAuthentication 政策,您會建立下列 ServiceEntry

apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
  name: "external-jwks-provider-se"
  namespace: your-namespace 
spec:
  hosts:
  - "your-auth-provider.com" # Hostname from your jwksUri
  location: MESH_EXTERNAL
  ports:
  - number: 443
    name: https
    protocol: TLS
  resolution: DNS

使用 DestinationRule 設定連線設定

其次,您可能需要DestinationRule,指定連線至 JWKS 提供者的用戶端 TLS 設定,尤其是當提供者要求特定的 TLS 或 mTLS 設定時。

  • 如果供應商使用公開信任的憑證,請建立 DestinationRule 並將 tls.mode 設為 SIMPLE,啟用標準伺服器端 TLS 驗證。
  • 如果供應商需要用戶端憑證 (mTLS),請將 tls.mode 設為 MUTUAL,並提供 Envoy 必須出示的憑證和金鑰路徑。

這個 DestinationRule 會為上一個步驟中定義的 ServiceEntry 設定連線政策:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: "external-jwks-provider-dr"
  namespace: your-namespace 
spec:
  host: "your-auth-provider.com" # Must match a host in the ServiceEntry
  trafficPolicy:
    tls:
      # Use SIMPLE for standard server-side TLS.
      mode: SIMPLE 
      
      # If the JWKS provider uses a custom CA, provide the CA cert bundle.
      # caCertificates: /path/to/provider-ca-cert.pem

      # For providers requiring mTLS from Envoy, uncomment the following:
      # mode: MUTUAL
      # clientCertificate: /path/to/client-cert.pem
      # privateKey: /path/to/client-key.pem
      # caCertificates: /path/to/provider-ca-cert.pem

如果這些資源存在且設定正確,Envoy 就會使用這些資源建立安全連線,並擷取 JWKS 金鑰。

2. Cloud Service Mesh 自動設定 (僅限 Traffic Director)

如果 Cloud Service Mesh 找不到涵蓋 HTTPS jwksUri 主機名稱和連接埠的使用者定義 ServiceEntry,就會自動設定 Envoy 擷取 JWKS 金鑰所需的設定。RequestAuthentication如果預設連線至 jwksUri (HTTPS、標準 TLS) 就足夠,這項自動化功能可簡化設定程序。

自動設定的條件:符合下列條件時,系統會自動執行這項操作:

  • 您正在使用 Cloud Service Mesh 和 Traffic Director。
  • jwksUri 使用 https 配置。
  • jwksUri 指向外部服務,而非叢集本機服務。
  • 沒有可見ServiceEntry (考量 RequestAuthentication 政策的命名空間和 ServiceEntryexportTo 欄位) 已管理 jwksUri 的主機名稱和連接埠。

如果符合這些條件,系統會設定 Envoy Proxy 來擷取 JWKS,您不需要為該 jwksUri 建立明確的 ServiceEntryDestinationRule 資源。

正在設定「RequestAuthentication

無論採用哪種 JWKS 擷取方法,您都可以使用 RequestAuthentication 政策定義 JWT 驗證規則。

apiVersion: security.istio.io/v1
kind: RequestAuthentication
metadata:
  name: "jwt-example"
  namespace: your-namespace # Replace with your application's namespace
spec:
  selector:
    matchLabels:
      app: your-app # Replace with your application's label (e.g. httpbin)
  jwtRules:
  - issuer: "testing@secure.istio.io"
    jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.26/security/tools/jwt/samples/jwks.json"

jwtRules 中的重要欄位 (詳情請參閱 Istio RequestAuthentication 說明文件):

  • issuer:JWT 的核發者。
  • jwksUri:供應商公開金鑰集 (JWKS) 的 HTTPS URI。
  • fromHeaders (選用):指定預期 JWT 所在的標頭位置。
  • fromParams (選用):指定預期 JWT 來源的查詢參數。
  • forwardOriginalToken (選用):如果為 true,原始權杖會轉送至上游服務。

使用 AuthorizationPolicy 強制執行 JWT 驗證

如要拒絕缺少有效 JWT 的要求,您必須將RequestAuthentication政策與AuthorizationPolicy配對。下列政策只允許來自指定簽發者和主體的有效 JWT,才能向 your-app 工作負載提出要求。

apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
 name: "require-jwt-for-your-app"
 namespace: your-namespace # Replace with your application's namespace
spec:
 selector:
   matchLabels:
     app: your-app # Replace with your application's label (e.g. httpbin)
 action: ALLOW
 rules:
 - from:
   - source:
       # This principal is typically in the format "issuer/subject"
       requestPrincipals: ["testing@secure.istio.io/sub-from-jwt"] # Replace with the expected principal

如要查看使用 JWT 聲明授權的詳細範例和用途,請參閱「Istio Authorization for JWT Tokens task」。

後續步驟