הגדרת אימות JWT באמצעות JWKS מרוחק

ב-Cloud Service Mesh אפשר לאבטח את השירותים באמצעות אימות של אסימוני JWT‏ (JSON Web Tokens) באמצעות המשאב המותאם אישית של Istio‏ RequestAuthentication. חלק מרכזי בהגדרה הזו הוא השדה jwksUri, שמציין את ה-URI של ספק ה-JSON Web Key Set‏ (JWKS). קובץ ה-JWKS הזה מכיל את המפתחות הציבוריים שמשמשים לאימות של JWT נכנסים.

חשוב: ב-Cloud Service Mesh, מישור הנתונים (Envoy proxies) אחראי לאחזור מפתחות JWKS ישירות מ-jwksUri. מישור הבקרה של Cloud Service Mesh (שמנוהל על ידי Traffic Director) לא מבצע קריאות חיצוניות כדי לאחזר את המפתחות האלה. כלומר, כל התקשורת ברשת עם ספקי JWKS חיצוניים מגיעה מ-Envoy proxy של עומס העבודה.

דרישות מוקדמות לגישה חיצונית למפתחות JWK

כדי לפעול לפי המדריך הזה, צריך:

  • מדיניות ארגונית לגישה לאינטרנט: אם jwksUri מצביע על נקודת קצה חיצונית באינטרנט, מדיניות הארגון Google Cloud צריכה לאפשר גישה לאינטרנט יוצאת מעומסי העבודה. בפרט, מוודאים שמדיניות הארגון constraints/compute.disableInternetNetworkEndpointGroup לא נאכפת. אם המדיניות הזו מופעלת, לא ניתן יהיה לאחזר JWKS משרתי jwksUri חיצוניים.

  • A Labeled Kubernetes Workload: המשאבים RequestAuthentication ו-AuthorizationPolicy משתמשים ב-selector כדי לטרגט עומסי עבודה ספציפיים. צריך להפעיל באשכול עומס עבודה, כמו Kubernetes Deployment, עם תוויות שהמדיניות יכולה להתאים להן. לדוגמה, הדגימה httpbin מוגדרת להפעלה עם התווית app: httpbin. אפשר להשתמש בהגדרה עם httpbin ועם curl מהמדריך Istio JWT Token.

שיטות להפעלת אחזור של JWKS

יש שתי דרכים עיקריות להגדיר את Cloud Service Mesh כדי לאפשר לשרתי ה-proxy של Envoy לאחזר מפתחות JWKS מ-jwksUri חיצוני:

זו הגישה המומלצת לרוב תרחישי הייצור, והיא נדרשת ל-Cloud Service Mesh עם MCP. השיטה הזו מאפשרת לכם שליטה מפורשת באופן שבו הרשת שלכם יוצרת אינטראקציה עם ספק ה-JWKS החיצוני.

הגדרת השירות החיצוני באמצעות ServiceEntry

קודם צריך ליצור Istio ServiceEntry כדי שספק ה-JWKS החיצוני יהיה שירות מוכר ברשת שלכם. המשאב הזה מאפשר פענוח DNS וניתוב תקין של שרתי ה-proxy של Envoy במישור הנתונים.

למדיניות RequestAuthentication שמשתמשת ב-jwksUri: "https://your-auth-provider.com/.well-known/jwks.json", יוצרים את 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 כדי לציין הגדרות TLS בצד הלקוח לחיבורים לספק JWKS, במיוחד אם הספק דורש הגדרת 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 לא מוצא ServiceEntry שהוגדר על ידי המשתמש ומכסה את שם המארח והיציאה של jwksUri HTTPS במדיניות RequestAuthentication, הוא יגדיר אוטומטית את ההגדרה הנדרשת כדי ש-Envoy יאחזר את מפתחות ה-JWKS. האוטומציה הזו מפשטת את ההגדרה בתרחישים נפוצים שבהם קישוריות ברירת המחדל ל-jwksUri (HTTPS, ‏ TLS רגיל) מספיקה.

תנאים להגדרה אוטומטית: ההתנהגות האוטומטית הזו מתרחשת אם:

  • אתם משתמשים ב-Cloud Service Mesh עם Traffic Director.
  • ה-jwksUri משתמש בסכימת https.
  • הנקודה jwksUri מצביעה על שירות חיצוני שלא נמצא באותו אשכול.
  • אין visible ServiceEntry (בהתחשב במרחב השמות של מדיניות RequestAuthentication ובשדה exportTo של ServiceEntry) שמנהל כבר את שם המארח והיציאה של jwksUri.

אם התנאים האלה מתקיימים, שרתי ה-proxy של Envoy יוגדרו לאחזור JWKS בלי שתצטרכו ליצור משאבי ServiceEntry או DestinationRule מפורשים עבור jwksUri.

הגדרה של RequestAuthentication

לא משנה באיזו שיטה משתמשים לאחזור JWKS, מגדירים כללי אימות של JWT באמצעות מדיניות 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"

שדות מפתח ב-jwtRules (פרטים מלאים זמינים במסמכי התיעוד של Istio RequestAuthentication):

  • issuer: הגורם שהנפיק את ה-JWT.
  • jwksUri: ה-URI של HTTPS של קבוצת המפתחות הציבוריים (JWKS) של הספק.
  • fromHeaders (אופציונלי): מציינים את המיקומים של הכותרות שמהם צפוי להגיע ה-JWT.
  • fromParams (אופציונלי): מציין פרמטרים של שאילתה שמהם צפוי ה-JWT.
  • forwardOriginalToken (אופציונלי): אם הערך הוא true, האסימון המקורי מועבר לשירות במעלה הזרם.

הפעלת אימות JWT באמצעות AuthorizationPolicy

כדי לדחות בקשות שחסר בהן אסימון JWT תקין, צריך לשייך את מדיניות RequestAuthentication ל-AuthorizationPolicy. המדיניות הבאה מאפשרת בקשות לעומס העבודה your-app רק אם הן כוללות JWT תקף מהמוסד המנפיק ומהנושא שצוינו.

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.

המאמרים הבאים