Mengonfigurasi autentikasi JWT dengan JWKS jarak jauh

Cloud Service Mesh memungkinkan Anda mengamankan layanan dengan memvalidasi Token Web JSON (JWT) menggunakan resource kustom RequestAuthentication Istio. Bagian penting dari konfigurasi ini adalah kolom jwksUri, yang menentukan URI penyedia JSON Web Key Set (JWKS). JWKS ini berisi kunci publik yang digunakan untuk memvalidasi JWT masuk.

Penting: Di Cloud Service Mesh, bidang data (proxy Envoy) bertanggung jawab untuk mengambil kunci JWKS langsung dari jwksUri. Bidang kontrol Cloud Service Mesh (dikelola oleh Traffic Director) tidak melakukan panggilan eksternal untuk mengambil kunci ini. Artinya, semua komunikasi jaringan ke penyedia JWKS eksternal berasal dari proxy Envoy beban kerja Anda.

Prasyarat untuk Akses JWKS Eksternal

Untuk mengikuti panduan ini, Anda memerlukan:

  • Kebijakan Organisasi untuk Akses Internet: Jika jwksUri Anda mengarah ke endpoint internet eksternal, kebijakan organisasi Google Cloud Anda harus mengizinkan akses internet keluar dari workload Anda. Secara khusus, pastikan kebijakan organisasi constraints/compute.disableInternetNetworkEndpointGroup tidak diterapkan. Jika kebijakan ini diaktifkan, pengambilan JWKS dari jwksUri eksternal akan gagal.

  • Workload Kubernetes Berlabel: Resource RequestAuthentication dan AuthorizationPolicy menggunakan selector untuk menargetkan workload tertentu. Anda harus memiliki workload, seperti Deployment Kubernetes, yang berjalan di cluster dengan label yang dapat dicocokkan oleh kebijakan. Misalnya, contoh httpbin dikonfigurasi untuk berjalan dengan label app: httpbin. Jangan ragu untuk menggunakan penyiapan dengan httpbin dan curl dari panduan Token JWT Istio.

Metode untuk Mengaktifkan Pengambilan JWKS

Ada dua cara utama untuk mengonfigurasi Cloud Service Mesh agar proxy Envoy Anda dapat mengambil kunci JWKS dari jwksUri eksternal:

Ini adalah pendekatan yang direkomendasikan untuk sebagian besar skenario produksi, dan diperlukan untuk Cloud Service Mesh dengan MCP. Metode ini memberi Anda kontrol eksplisit atas cara mesh Anda berinteraksi dengan penyedia JWKS eksternal.

Menentukan layanan eksternal dengan ServiceEntry

Pertama, Anda harus membuat ServiceEntry Istio untuk menjadikan penyedia JWKS eksternal sebagai layanan yang dikenal dalam mesh Anda. Resource ini memungkinkan resolusi DNS dan perutean yang tepat untuk proxy Envoy di bidang data Anda.

Untuk kebijakan RequestAuthentication yang menggunakan jwksUri: "https://your-auth-provider.com/.well-known/jwks.json", Anda akan membuat ServiceEntry berikut:

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

Mengonfigurasi setelan koneksi dengan DestinationRule

Kedua, Anda mungkin memerlukan DestinationRule untuk menentukan setelan TLS sisi klien untuk koneksi ke penyedia JWKS, terutama jika penyedia memerlukan konfigurasi TLS atau mTLS tertentu.

  • Untuk penyedia yang menggunakan sertifikat tepercaya publik, buat DestinationRule dengan tls.mode yang disetel ke SIMPLE untuk mengaktifkan validasi TLS sisi server standar.
  • Untuk penyedia yang memerlukan sertifikat klien (mTLS), tetapkan tls.mode ke MUTUAL dan berikan jalur ke sertifikat dan kunci yang harus diberikan Envoy.

DestinationRule ini mengonfigurasi kebijakan koneksi untuk ServiceEntry yang ditentukan pada langkah sebelumnya:

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

Menangani Traffic Aplikasi ke Penyedia JWKS yang Sama

Dalam beberapa kasus, aplikasi Anda mungkin perlu berkomunikasi langsung dengan layanan eksternal yang sama yang menyediakan jwksUri. Misalnya, aplikasi Anda mungkin perlu memanggil endpoint autentikasi di your-auth-provider.com sementara Cloud Service Mesh mengambil kunci JWKS dari host yang sama.

Jika Anda mengikuti konfigurasi DestinationRule standar dengan tls: mode: SIMPLE, semua traffic dari mesh Anda ke your-auth-provider.com akan memiliki TLS yang berasal dari proxy Envoy. Jika aplikasi Anda juga memulai TLS untuk permintaannya ke host yang sama, hal ini dapat menyebabkan error koneksi untuk traffic aplikasi karena masalah enkripsi "TLS ganda".

Untuk mengatasinya, Anda dapat menggunakan DestinationRule dengan subset untuk menerapkan kebijakan TLS yang berbeda untuk pengambilan JWKS dan untuk traffic aplikasi.

  1. Buat ServiceEntry seperti biasa:

    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
    
  2. Buat DestinationRule dengan kebijakan traffic untuk pengambilan JWKS dan subset untuk traffic aplikasi:

    • Setelan trafficPolicy default mengaktifkan pembuatan TLS untuk pengambilan JWKS Cloud Service Mesh.
    • Bernama subset (misalnya, app-traffic) menonaktifkan asal TLS Cloud Service Mesh, sehingga aplikasi dapat menangani TLS sendiri.
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: "external-jwks-provider-dr"
      namespace: your-namespace
    spec:
      host: "your-auth-provider.com"
      trafficPolicy:
        tls:
          mode: SIMPLE
      subsets:
      - name: app-traffic
        trafficPolicy:
          tls:
            # Use DISABLE to prevent Envoy from originating TLS for the application's traffic
            mode: DISABLE
    
  3. Buat VirtualService untuk merutekan traffic aplikasi ke subset yang sesuai: VirtualService ini memastikan bahwa traffic dari aplikasi Anda ke host eksternal dikirim ke subset app-traffic, yang melewati TLS origination Cloud Service Mesh.

    apiVersion: networking.istio.io/v1beta1
    kind: VirtualService
    metadata:
      name: "route-for-app-to-jwks-provider"
      namespace: your-namespace # The namespace of your application
    spec:
      hosts:
      - "your-auth-provider.com"
      http:
      - route:
        - destination:
            host: "your-auth-provider.com"
            subset: app-traffic
    

Dengan konfigurasi ini, Anda dapat mengambil kunci JWKS dengan aman untuk autentikasi JWT sekaligus memungkinkan aplikasi Anda berkomunikasi langsung dengan penyedia eksternal yang sama tanpa konflik.

2. Konfigurasi Otomatis oleh Cloud Service Mesh (Khusus Traffic Director)

Jika Cloud Service Mesh tidak menemukan ServiceEntry yang ditentukan pengguna yang mencakup nama host dan port jwksUri HTTPS dalam kebijakan RequestAuthentication, Cloud Service Mesh akan otomatis mengonfigurasi penyiapan yang diperlukan agar Envoy mengambil kunci JWKS. Otomatisasi ini menyederhanakan penyiapan untuk skenario umum yang konektivitas default ke jwksUri (HTTPS, TLS standar) sudah cukup.

Kondisi untuk Konfigurasi Otomatis: Perilaku otomatis ini berlaku jika:

  • Anda menggunakan Cloud Service Mesh dengan Traffic Director.
  • jwksUri menggunakan skema https.
  • jwksUri mengarah ke layanan eksternal yang tidak bersifat lokal untuk cluster.
  • Tidak ada terlihat ServiceEntry (dengan mempertimbangkan namespace kebijakan RequestAuthentication dan kolom exportTo ServiceEntry) yang sudah mengelola nama host dan port jwksUri.

Jika kondisi ini terpenuhi, proxy Envoy Anda akan dikonfigurasi untuk mengambil JWKS tanpa mengharuskan Anda membuat resource ServiceEntry atau DestinationRule eksplisit untuk jwksUri tersebut.

Mengonfigurasi RequestAuthentication

Terlepas dari metode yang digunakan untuk pengambilan JWKS, Anda menentukan aturan validasi JWT menggunakan kebijakan RequestAuthentication.

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"

Kolom utama di jwtRules (lihat dokumentasi Istio RequestAuthentication untuk mengetahui detail selengkapnya):

  • issuer: Penerbit JWT.
  • jwksUri: URI HTTPS set kunci publik (JWKS) penyedia.
  • fromHeaders (Opsional): Menentukan lokasi header yang diharapkan JWT berasal dari sana.
  • fromParams (Opsional): Menentukan parameter kueri yang diharapkan dari JWT.
  • forwardOriginalToken (Opsional): Jika benar (true), token asli akan diteruskan ke layanan upstream.

Menerapkan Autentikasi JWT dengan AuthorizationPolicy

Untuk menolak permintaan yang tidak memiliki JWT yang valid, Anda harus memasangkan kebijakan RequestAuthentication dengan AuthorizationPolicy. Kebijakan berikut mengizinkan permintaan ke workload your-app hanya jika permintaan tersebut menyajikan JWT yang valid dari penerbit dan subjek yang ditentukan.

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

Untuk contoh dan kasus penggunaan yang lebih mendetail tentang penggunaan klaim JWT dalam otorisasi, lihat tugas Otorisasi Istio untuk Token JWT.

Langkah Berikutnya