סוכני Google Kubernetes Engine (GKE) שיש להם זהות סוכן יכולים להשתמש בה כדי לבצע אימות לממשקי Google Cloud API ולכלים ולשירותים חיצוניים. הסוכנים יכולים להשתמש בזהות שלהם או לפעול בשם משתמשי הקצה. במאמר הזה נסביר למפתחי אפליקציות של סוכנים איך להגדיר את האפליקציות שלהם כדי לבצע אימות למשאבים שונים. כדאי שתקראו את המאמר בנושא בקשת זהות של סוכן עבור סוכן GKE.
בהתאם למשאב שהסוכן צריך לגשת אליו, יכול להיות שהאדמין של הפלטפורמה יצטרך להגדיר את כספת האישורים של מנהל ההרשאות כדי להפעיל תהליכי עבודה נוספים. לדוגמה, כדי שסוכן יוכל לבצע אימות ב-GitHub בשם משתמש קצה, ספק אימות OAuth עם 3 רגליים במנהל האימות צריך לטפל בכניסה, בהרשאה ובהפניה אוטומטית של המשתמש. המפתחים צריכים לשנות את הסוכן כדי שהוא יפנה לספק האימות הנכון ויטפל בהמשך השיחה עם משתמש הקצה.
מגבלות
- מגבלות על זהות הסוכן
- אפשר להשתמש בספריית האימות של Google כדי לקבל אסימוני גישה ואסימוני מזהה רק עבור Python. יכול להיות שספריית האימות לא תקבל טוקנים של שפות אחרות. אם אתם משתמשים בשפה אחרת, אתם יכולים לעבור לאסימונים לא קשורים על ידי הגדרת משתנה הסביבה
GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKENלערךfalse.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שביצעתם את המשימות הבאות:
- מפעילים את ממשק ה-API של Google Kubernetes Engine. הפעלת Google Kubernetes Engine API
- כדי להשתמש ב-CLI של Google Cloud למשימה הזו, צריך להתקין ואז לאתחל את ה-CLI של gcloud. אם התקנתם בעבר את ה-CLI של gcloud, מריצים את הפקודה
gcloud components updateכדי לקבל את הגרסה העדכנית. יכול להיות שגרסאות קודמות של ה-CLI של gcloud לא יתמכו בהרצת הפקודות שמופיעות במסמך הזה.
- מתחברים לאשכול קיים שמופעל בו עומס עבודה שמשתמש בזהות סוכן. כדי לבקש זהות של סוכן עבור עומס עבודה, אפשר לעיין במאמר בקשת זהות של סוכן עבור סוכן GKE.
- כדי לבצע אימות לכלים ולשירותים חיצוניים באמצעות כלי ניהול ההרשאות, צריך לבקש מאדמין הפלטפורמה לבצע את הפעולות הבאות:
- מגדירים ספק אימות לתהליך העבודה של האימות.
- מתן גישה לסוכן אל ספק האימות.
התפקידים הנדרשים
כדי לקבל את ההרשאות שנדרשות להגדרת סוכנים שנפרסו באשכולות GKE, צריך לבקש מהאדמין להקצות לכם את תפקיד ה-IAM Kubernetes Engine Developer (roles/container.developer) בפרויקט.
כדי לקרוא הסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
אימות ל- Google Cloud APIs
כדי לבצע אימות לממשקי Google Cloud API בתור הזהות של הסוכן, הסוכן יכול להשתמש באסימון גישה לזהות הסוכן משרת המטא-נתונים בצמתים. השינויים שתצטרכו לבצע בקוד תלויים באופן שבו אתם קוראים ל-API של Google Cloud , כמו שמתואר בהמשך.
שימוש בספריות לקוח ב-Cloud
אם אתם משתמשים בגרסה של ספריות הלקוח ב-Cloud שכוללת את גרסה 2.61.0 ואילך של ספריית google-auth, אז Application Default Credentials (ADC) מקבל באופן אוטומטי אסימון גישה לזהות של הסוכן. לא צריך לבצע שינויים נוספים בקוד. אם מפעילים הזרקת אישורים ל-Pods על ידי הגדרת ההערה iam.gke.io/inject-podcertificates: "true", אסימון הגישה משויך לאישור X.509 כברירת מחדל, אלא אם משביתים את האסימונים המשויכים.
כדי לקבל טוקנים לא מאוגדים לגישה כשמשתמשים בספריות הלקוח של Cloud, מבצעים אחת מהפעולות הבאות:
- מפעילים את הזרקת האישורים ב-Pod ומגדירים את משתנה הסביבה
GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKENל-false. - אל תפעילו הוספה של אישורים ב-Pod.
שימוש בקריאות ישירות לנקודות קצה של Google Cloud API
אם אתם לא משתמשים בספריות הלקוח ב-Cloud כדי ליצור אינטראקציה עם שירות, אתם יכולים להשתמש בזהות של הסוכן כדי לבצע אימות ל-API Google Cloud באופן הבא:
קבלת אסימון גישה משרת המטא-נתונים בצומת. אפשר לקבל טוקן באחת מהשיטות הבאות:
טוקני גישה מאוגדים: משתמשים בספריית Python
google-auth, שמגלה את אישור X.509 של ה-Pod ומקבלת אוטומטית טוקני גישה מאוגדים כברירת מחדל. בשפות תכנות אחרות, משתמשים בטוקנים לא קשורים.Unbound access tokens: אם ל-Pod אין את חבילת האישורים של זהות הסוכן, צריך להשתמש בספריית האימות של Google בשפת התכנות שלכם. ספריית האימות מקבלת באופן אוטומטי טוקני גישה לא קשורים ומרעננת טוקנים שתוקפם עומד לפוג. באפליקציות Python ב-Pods שיש להן את חבילת פרטי הכניסה, מגדירים את משתנה הסביבה
GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKENבמפרט ה-Pod לערךfalse, כמו בדוגמה הבאה:# Multiple lines are omitted here. spec: containers: - name: example-agent image: example-image env: - name: GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKEN value: "false" # Multiple lines are omitted here.משתנה הסביבה הזה מונע מהספרייה לקבל אסימוני גישה ואסימוני זהות שקשורים ל-Bound.
עבור טוקני גישה קשורים, שלח את הבקשה לנקודת הקצה של mTLS ב-API וכלול את שרשרת האישורים של זהות הסוכן X.509 בתעבורת ה-HTTP. אם אתם משתמשים בספריית האימות של Google עבור Python, הספרייה מטפלת בשבילכם בהגדרת התעבורה ב-HTTP.
בדוגמה הבאה אפשר לראות איך משתמשים בספריית האימות של Google ל-Python כדי לקבל אסימון גישה מאוגד ולשלוח בקשה לנקודת הקצה של Cloud Storage mTLS:
import google.auth
from google.auth.transport.requests import AuthorizedSession
def call_storage_api_mtls(bucket_name: str) -> None:
# Discover the Pod's X.509 certificate chain by using the auth library
credentials, project = google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
# Configure the mTLS session by using the Pod's certificate chain
session = AuthorizedSession(credentials)
session.configure_mtls_channel()
# Call the Google Cloud mTLS endpoint
mtls_url = f"https://storage.mtls.googleapis.com/storage/v1/b/{bucket_name}/o"
response = session.get(mtls_url)
response.raise_for_status()
print(response.json())
אימות מול כלים ושירותים חיצוניים
כדי לאמת לכלים ולשירותים חיצוניים, אפשר להגדיר את הסוכן כך שיקבל את פרטי הכניסה הנדרשים ממנהל האימות של Agent Identity. אדמין של פלטפורמה מגדיר ספקי אימות שונים במנהל האימות. כל אחד מהם מנהל תהליכי עבודה ופרטי כניסה ספציפיים לאימות. משנים את קוד האפליקציה כדי לקרוא לספק אימות ספציפי, ובהתאם לתהליך האימות, כדי לטפל בהסכמת המשתמשים ובחידוש השיחה. השינויים הספציפיים שאתם מבצעים בסוכן תלויים בגישה שאתם צריכים, באופן הבא:
- כדי לגשת לשירותים חיצוניים בשם משתמש קצה, מבצעים את הפעולות הבאות:
- משנים את הסוכן כדי לקרוא לספק אימות מסוג OAuth תלת-רגלי.
- משנים את האפליקציה בצד הלקוח כדי לטפל בכניסה של משתמשים ובהפניה אוטומטית.
- כדי לגשת לשירותים חיצוניים באמצעות ההרשאה של הסוכן, צריך לשנות את הסוכן כך שיקרא לספק אימות OAuth דו-רגלי.
- כדי לגשת לממשקי API חיצוניים באמצעות מפתח API, צריך לשנות את הסוכן כדי לקרוא לספק אימות של מפתח API.
מנהל ההרשאות מטפל בתהליכי העבודה המתאימים לאימות ונותן לסוכן גישה לפרטי הכניסה המוצפנים, שאפשר לכלול אותם בבקשות לשירות החיצוני. מידע נוסף על הפעולות שאדמין הפלטפורמה צריך לבצע כדי להגדיר את ספקי האימות האלה ולהעניק גישה לזהות הסוכן שלכם זמין במאמר תהליכי עבודה לאימות סוכנים.
אימות לסוכנים אחרים
בארכיטקטורות מרובות סוכנים, הסוכנים משתפים פעולה לעיתים קרובות על ידי הפעלה ישירה של סוכנים עמיתים או שירותים במורד הזרם. אפשר ליצור תקשורת ישירה בין עומסי עבודה של סוכנים באמצעות אסימוני זהות. אפשר לקבל טוקן של מזהה קשור או לא קשור משרת המטא-נתונים של GKE ולהשתמש בטוקן הזה כדי לבצע אימות ישירות לסוכנים אחרים.
כדי לקבל טוקן של מזהה ולהשתמש בטוקן בבקשת HTTP, צריך להשתמש בספריית האימות של Google ל-Python. הספרייה מטפלת באופן אוטומטי באיתור האישורים ובהשגת טוקן של מזהה. אם משתמשים בשפת תכנות אחרת, יכול להיות שספריית האימות של Google לא תקבל אסימוני מזהה מאוגדים. במקום זאת, כדאי לעבור לטוקנים של מזהה לא קשורים.
קבלת טוקן של מזהה
כדי לבקש אסימון מזהה בקוד של הסוכן, צריך להשתמש בספריית האימות של Google שמתאימה לשפת התכנות שלכם. אפשר להשתמש בספרייה כדי לבקש טוקנים של מזהה קשורים או לא קשורים, באופן הבא:
- טוקנים של מזהה מאוגדים: משתמשים באנוטציה ה-
iam.gke.io/inject-podcertificates: "true"כדי להפעיל הוספה של אישור ל-Pod. ספריית האימות של Python שולחת באופן אוטומטי בקשה לטוקן של מזהה שקשור לאישור משרת המטא-נתונים של GKE. משתמשים בטוקנים של מזהה מאוגדים כשמבצעים אימות בין סוכנים שפועלים ב- Google Cloud באמצעות mTLS. טוקנים של מזהה לא קשורים:
- מפעילים את הזרקת האישורים ל-Pod ומבצעים אחת מהפעולות הבאות:
- בקוד האפליקציה, בפונקציה
id_token.fetch_id_token, מגדירים את הארגומנטbind_id_tokenלערךFalse. הארגומנט הזה גורם לספריית האימות לבקש טוקנים של מזהה לא מאוגד. בקשות לטוקן גישה לא מושפעות. - במפרט ה-Pod, מגדירים את משתנה הסביבה
GOOGLE_API_ENABLE_RUNTIME_BOUND_TOKENלערךfalse. משתנה הסביבה הזה מונע מהספרייה לבקש טוקני גישה וטוקנים של מזהה שקשורים ל-bound.
- בקוד האפליקציה, בפונקציה
- לא מפעילים הוספת אישורים ל-Pod. ספריית האימות מקבלת טוקן של מזהה לא מאוגד, כי אין חבילת אישורים ב-Pod.
משתמשים בטוקנים של מזהה לא קשורים כשמבצעים אימות ל-API Google Cloud , לשירותים חיצוניים או לסוכנים אחרים באמצעות חיבור שאינו mTLS.
- מפעילים את הזרקת האישורים ל-Pod ומבצעים אחת מהפעולות הבאות:
בדוגמאות הבאות מוצגות בקשות לאסימון מזהה מאוגד או לא מאוגד עבור סוכן שהפעלתם בו הזרקת פרטי כניסה:
שליחת בקשה לטוקן של מזהה מאוגד:
import google.auth.transport.requests from google.oauth2 import id_token # Application Default Credentials automatically requests a certificate-bound # ID token. def get_bound_id_token(target_audience: str) -> str: auth_req = google.auth.transport.requests.Request() return id_token.fetch_id_token(auth_req, audience=target_audience)אסימון הזהות המקשר כולל את טביעת האצבע לאישור SHA-256 של רשת אישורי ה-X.509 של ה-Pod בפרמטר
cnf.x5t#S256.שליחת בקשה לאסימון מזהה לא מאוגד:
import google.auth.transport.requests from google.oauth2 import id_token def get_unbound_id_token(target_audience: str) -> str: auth_req = google.auth.transport.requests.Request() return id_token.fetch_id_token( auth_req, audience=target_audience, # Always get an unbound ID token, even if the Pod has a credential # bundle. bind_id_token=False, )
שימוש בטוקן של מזהה בבקשה לסוכן אחר
אחרי שמקבלים טוקן של מזהה לסוכן, אפשר להשתמש בטוקן כדי לבצע אימות ישירות לסוכן אחר. האימות של החיבור תלוי בשאלה אם משתמשים בטוקן של מזהה מאוגד, באופן הבא:
- כדי להשתמש בטוקנים של מזהה קשורים, צריך ליצור חיבור mTLS עם הסוכן המקבל ולאמת את החיבור באמצעות שני סוגי האישורים הבאים מתיקיית
/var/run/secrets/workload-spiffe-credentials/ב-Pod:- חבילת פרטי הכניסה של זהות הסוכן שנמצאת בקובץ
x509.credential-bundle.private-key.pem, שמכילה את שרשרת האישורים של עלה העץ עבור ה-Pod. - חבילת האישורים של האשכול שנמצאת בקובץ
TRUST_DOMAIN.spiffe-trust-bundle.pem. הקובץ הזה מכיל את אישור ה-CA הבסיסי של הסוכן המקבל, והוא משמש לאימות שרשרת האישורים של הסוכן המקבל במהלך לחיצת היד של mTLS. הנציגים שמבצעים את השיחה ומקבלים אותה צריכים להיות באותו מאגר זהויות של נציגים.
- חבילת פרטי הכניסה של זהות הסוכן שנמצאת בקובץ
- במקרה של טוקנים של מזהה לא קשורים, צריך ליצור חיבור לא mTLS עם הסוכן המקבל.
בדוגמאות הבאות מוצגות דרכים לשליחת בקשה לסוכן אחר באמצעות טוקן של מזהה קשור או לא קשור:
טוקן של מזהה מאוגד: כוללים את טוקן הזהות המאוגד בכותרת
Authorization: Bearerשל הבקשה ששולחים לנקודת הקצה של mTLS של הסוכן המקבל. מאמתים את חיבור ה-TLS באמצעות אישור X.509 והמפתח הפרטי של ה-Pod:import ssl import urllib3 BUNDLE_PATH = "/var/run/secrets/workload-spiffe-credentials/x509.credential-bundle.private-key.pem" TRUST_BUNDLE_PATH = "/var/run/secrets/workload-spiffe-credentials/TRUST_DOMAIN.spiffe-trust-bundle.pem" def call_peer_agent_bound_mtls(target_mtls_url: str, target_audience: str) -> None: # Configure the mTLS context by using the certificate chain and trust # bundle from the Pod. ctx = ssl.create_default_context(cafile=TRUST_BUNDLE_PATH) ctx.load_cert_chain(BUNDLE_PATH) http = urllib3.PoolManager(ssl_context=ctx, assert_hostname=False) # Call a peer agent's mTLS endpoint by using the bound ID token and Pod # certificate chain. bound_id_token = get_bound_id_token(target_audience) response = http.request( "POST", target_mtls_url, headers={"Authorization": f"Bearer {bound_id_token}"}, json={"task": "analyze_data"}, timeout=10, ) print(response.json())מחליפים את
TRUST_DOMAINבמתחם האמון (trust domain) של מאגר הזהויות של הסוכן.טוקן של מזהה לא קשור: כוללים את הטוקן בכותרת
Authorization: Bearerשל הבקשה לסוכן העמית:import requests def call_peer_agent_unbound(target_url: str, target_audience: str) -> None: unbound_id_token = get_unbound_id_token(target_audience) # Send the request by using a standard TLS connection or plain HTTP. response = requests.post( target_url, headers={"Authorization": f"Bearer {unbound_id_token}"}, json={"task": "analyze_data"}, timeout=10, ) response.raise_for_status() print(response.json())
אימות הבקשה בסוכן המקבל
בסוכן המקבל, מאמתים את אסימון ה-ID שנמצא בבקשה הנכנסת באופן הבא. אפשר להשתמש בספריות קריפטוגרפיות כמו Tink כדי לבצע את שלבי האימות האלה במקום לכתוב קוד בהתאמה אישית.
- מחולצים את טוקן הזהות מהכותרת
Authorization: Bearerשל הבקשה. - מוודאים שההצהרה
iss(מנפיק) בטוקן של מזהה היא מאגר הזהויות של הסוכן עבור הסוכן שקורא ל-API. המנפיק הוא אחד מהבאים, בהתאם לשאלה אם הסוכן שמבצע את הקריאה נמצא בפרויקט ששייך לארגון:- פרויקט שנמצא בארגון:
https://sts.googleapis.com/v1/organizations/ORGANIZATION_ID/locations/global/workloadIdentityPools/agents.global.org-ORGANIZATION_ID.system.id.goog, כאשרORGANIZATION_IDהוא מזהה הארגון שמכיל את הפרויקט של הסוכן שקורא ל-API. - Project that isn't in an organization:
https://sts.googleapis.com/v1/projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/agents.global.proj-PROJECT_NUMBER.system.id.goog, כאשרPROJECT_NUMBERהוא מספר הפרויקט של אשכול GKE של הסוכן המתקשר.
- פרויקט שנמצא בארגון:
- מאתרים את ה-URI של JSON Web Key Set (JWKS) עבור המנפיק ומאחסנים במטמון את מפתחות ה-JSON Web Keys (JWKs) הציבוריים. נקודת הקצה של JWKS היא בפורמט
ISSUER_URL/openid/jwks, כאשרISSUER_URLהיא כתובת ה-URL של המנפיק. - כדי לאמת את חתימת הטוקן של מזהה, משתמשים במידע הבא מכותרת ה-JOSE של הטוקן של מזהה:
- מפתח ה-JWK הציבורי שתואם לפרמטר הכותרת
kid. - האלגוריתם הקריפטוגרפי שתואם לפרמטר הכותרת
alg, כמוRS256.
- מפתח ה-JWK הציבורי שתואם לפרמטר הכותרת
- מוודאים שטביעת האצבע לאישור SHA-256 שנמצאת בפרמטר
cnf.x5t#S256תואמת לטביעת האצבע לאישור X.509 שסוכן הקריאה השתמש בו כדי לאמת את חיבור ה-mTLS. - בודקים את הטענות הבאות בטוקן ה-ID:
- זמן התפוגה בהצהרת
expהוא עתידי. - קהל היעד בטענה
audהוא הסוכן המקבל.
- זמן התפוגה בהצהרת
- מאשרים את הבקשה על סמך מזהה SPIFFE שנמצא בהצהרה
sub(subject) של האסימון.
המאמרים הבאים
- ניהול הגישה לממשקי Google Cloud API של סוכנים
- הגדרת מעקב לסוכנים
- הגדרת רישום ביומן לסוכנים
- הגדרת מעקב אחרי סוכנים