1. מבוא
סקירה כללית
במאמר יצירת מערכת מרובת סוכנים, יצרתם מערכת מבוזרת ליצירת קורסים, ובמאמר מבדיקות סובייקטיביות לא מבוססות להערכת סוכנים מבוססת-נתונים, למדתם איך להעריך את הביצועים שלה.
ב-Lab הזה מתמקדים בחיזוק המערכת על ידי טיפול בפערים האלה באבטחה. חשיפת נקודות קצה של סוכנים הופכת אותן למטרות להחדרת פרומפטים, למניעת שירות ולהתקפות ניצול אחרות. סוכנים שמקיימים אינטראקציה עם משתמשים עלולים לעבד פרטים אישיים רגישים מזהים (PII), בעוד שסוכנים שסורקים את האינטרנט עלולים להטמיע תוכן פוגעני או ליפול קורבן להחדרת פרומפטים. כדי להתמודד עם האיומים האלה, תטמיעו אסטרטגיית הגנה נרחבת באמצעות כלי האבטחה של Google Cloud, כולל Model Armor ו-Sensitive Data Protection, ותיישמו שיטות מומלצות לאבטחה כמו IAM עם הרשאות מינימליות ותקשורת מאומתת ברשת.
הפעולות שתבצעו:
- הגדרת מדיניות אבטחה: יצירת תבניות של Sensitive Data Protection (SDP) כדי לזהות ולערוך פרטים אישיים מזהים (PII).
- שילוב של Application Safety: צריך לשנות את הקצה העורפי כדי ליירט את ההנחיות של המשתמשים ולנקות אותן באמצעות Model Armor לפני שהן מגיעות לסוכנים.
- אימות הגנה: פרוס את האפליקציה המאובטחת והרץ תרחישי צוות אדום כדי לאמת שהחדרת פרומפטים ודליפות מידע אישי רגיש חסומות.
- הטמעה של מדיניות כקוד (אופציונלי): אפשר להשתמש ב-Terraform כדי לנהל את התבניות של הגנה מוגברת על המודל ו-SDP, וכך לוודא שמסנני האבטחה או אמצעי הבקרה יהיו עקביים בכל הסביבות.
מה תלמדו
- איך מגדירים את Sensitive Data Protection (SDP) ב-Google Cloud כדי לזהות ולבצע אנונימיזציה של מידע אישי רגיש.
- איך יוצרים ופורסים תבניות של הגנה מוגברת על המודל באמצעות Terraform.
- התבנית 'הגנה לעומק' לאבטחת סוכני AI גנרטיבי בשכבת האפליקציה.
- איך מבצעים ביקורת ומאמתים אמצעי בקרה לאבטחה באמצעות טכניקות של צוות אדום.
2. הגדרה
הגדרות אישיות
- ודא שאתה מחובר. מריצים את הפקודה הבאה כדי לקבל את חשבון gcloud הנוכחי:
אם לא נכנסתם לחשבון, מריצים את הפקודה הבאה:gcloud config get-value accountgcloud auth login --update-adc - מגדירים פרויקט פעיל ל-CLI של gcloud.מריצים את הפקודה הבאה כדי לקבל את הפרויקט הנוכחי של gcloud:
אם היא לא מוגדרת, מריצים את הפקודה הבאה:gcloud config get-value project מחליפים אתgcloud config set project YOUR_PROJECT_IDYOUR_PROJECT_IDבמזהה הפרויקט.
- מפעילים את ה-API של Cloud Run, הגנה מוגברת על המודל, Data Loss Prevention, Artifact Registry, Cloud Build ו-IAM Credentials.
gcloud services enable --project $(gcloud config get-value project) \ aiplatform.googleapis.com \ modelarmor.googleapis.com \ dlp.googleapis.com \ run.googleapis.com \ artifactregistry.googleapis.com \ cloudbuild.googleapis.com \ iamcredentials.googleapis.com - מגדירים את אזור ברירת המחדל שבו ייפרסו שירותי Cloud Run.
חשוב להשתמש ב-gcloud config set run/region us-central1us-central1כדי לגשת להגנה מוגברת על המודל ולקבל דוגמאות עקביות. כאן אפשר לראות את האזורים שבהם Model Armor זמין.
קוד ויחסי תלות
- משכפלים את קוד נקודת ההתחלה ומעבירים את הספרייה לשורש הפרויקט.
כדי להפעיל סביבת עבודה של Cloud Shell, מריצים את הפקודה הבאה:git clone https://github.com/h3xar0n/prai-roadshow-lab-3-starter cd prai-roadshow-lab-3-starter משתמשים באפשרות Terminal > New Terminal כדי לפתוח טרמינל חדש.cloudshell workspace . - כדי ליצור קובץ
.env, מזינים את הפקודות הבאות בטרמינל: ב-Cloud Shell Editor, משתמשים באפשרות View > Toggle Hidden Files (תצוגה > החלפת קבצים מוסתרים) כדי לראות קבצים מוסתרים, כמוecho "GOOGLE_GENAI_USE_VERTEXAI=true" > .env echo "GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project -q)" >> .env echo "GOOGLE_CLOUD_REGION=$(gcloud config get-value run/region -q)" >> .env echo "GOOGLE_CLOUD_LOCATION=global" >> .env.env. - כדי להתקין את יחסי התלות, מזינים את הפקודות הבאות בטרמינל:
uv sync
3. יצירת תבניות של Sensitive Data Protection
התכונה 'מתקדמת' של Model Armor להגנה על מידע רגיש משולבת עם Cloud DLP (Sensitive Data Protection) כדי לבדוק תוכן ולהסיר ממנו פרטים מזהים. כדי להשתמש בו לצורך צנזורה, צריך קודם ליצור תבניות של Inspect ושל הסרת פרטי הזיהוי, שבהן מציינים אילו סוגים של מידע אישי רגיש להפוך ואיך להפוך אותם. 
יצירת תבנית בדיקה
התכונה Sensitive Data Protection מוצאת סוגים שונים של מידע אישי רגיש באמצעות גלאי infoType. יש יותר מ-150 מזהים מובנים שמשתמשים בשיטות שונות לזיהוי, כולל התאמת תבניות (regex), מילונים ואותות מבוססי-הקשר. בסוגים מסוימים, כמו מספרי כרטיסי אשראי או תעודות מזהות רשמיות, המערכת לא מסתפקת בהתאמה פשוטה לתבנית, אלא גם מאמתת סכומי ביקורת כדי לצמצם את מספר התוצאות החיוביות הכוזבות. הגלאים האלה מכסים פרטים אישיים מזהים (PII) כמו שמות וכתובות, אבל גם פרטי כניסה כמו מפתחות API או אסימוני אימות, וזה שימושי במיוחד למניעת חשיפה של סוכנים שמבצעים אינטראקציה עם קוד או קוראים קוד.
- במסוף Google Cloud, עוברים אל Security (אבטחה) > Sensitive Data Protection (הגנה על מידע אישי רגיש).
- בתפריט הניווט, בוחרים באפשרות הגדרה > תבניות.
- לוחצים על יצירת תבנית.
- מגדירים את התבנית:
- סוג התבנית:
Inspect - מזהה תבנית:
sensitive-data-inspector - סוג המיקום:
Region - אזור:
us-central1(הפרמטר הזה נחוץ כדי לעבוד עם Model Armor).
- סוג התבנית:
- לוחצים על המשך.
- בקטע הגדרת זיהוי, לוחצים על ניהול סוגי מידע.
- משתמשים במסנן כדי לחפש את infoTypes הבאים ומסמנים את התיבה לצד כל אחד מהם:
CREDIT_CARD_NUMBERGOVERNMENT_IDPERSON_NAMEEMAIL_ADDRESSSTREET_ADDRESSSECURITY_DATA
- בוחרים נושאים נוספים שמעניינים אתכם ולוחצים על סיום.
- בצד שמאל, אפשר לבדוק מה יהיו הקלט והפלט עבור הסוגים השונים של מידע אישי רגיש שבחרתם.

- בודקים את הטבלה שנוצרה כדי לוודא שכל סוגי המידע האלה נוספו, ואז לוחצים על יצירה.
יצירת תבנית לביטול הזיהוי
עכשיו ניצור תבנית להסרת פרטי הזיהוי שמציינת איך לשנות את הממצאים של מידע אישי רגיש.
התכונה Sensitive Data Protection תומכת בשיטות רבות ושונות של טרנספורמציה. יכול להיות שתרצו לצנזר פרטים אישיים מזהים כמו כתובות מגורים באופן מלא, ולהחליף אותם בתווים כמו [REDACTED], אבל כשמדובר במספר כרטיס אשראי או במספר תעודת זהות, יכול להיות שתעדיפו להסתיר אותו באמצעות תו כמו #, ולהשאיר את 4 הספרות האחרונות גלויות לצורכי זיהוי. רשימה מלאה של שיטות טרנספורמציה שמאפשרות לאזן בין אבטחה לבין שימושיות מופיעה במאמר טכניקות להסרת פרטים מזהים.
- במסוף Google Cloud, עוברים אל Security (אבטחה) > Sensitive Data Protection (הגנה על מידע אישי רגיש).
- בתפריט הניווט, בחר תצורה > תבניות > ביטול זיהוי.
- לוחצים על יצירת תבנית.
- הגדר את התבנית:
- סוג התבנית:
De-identify - סוג טרנספורמציית הנתונים:
InfoType - מזהה תבנית:
sensitive-data-redactor - סוג מיקום:
Region - אזור:
us-central1(הפרמטר הזה נחוץ כדי לעבוד עם Model Armor).
- סוג התבנית:
- לוחצים על המשך.
- בקטע Configure de-identification, מגדירים כמה כללים. כללים עבור סוגי מידע ספציפיים עוקפים את כלל ברירת המחדל.
- מגדירים את כלל ההמרה הראשון:
- טרנספורמציה:
Mask with character - תו למיסוך:
# - תווים להתעלמות > ציון תווים להתעלמות:
US Punctuation... - מספר התווים שיוסתר:
12 - infoTypes to transform:
Specific infoTypes - לחץ על נהל סוגי מידע
- מחפשים ואז מסמנים את התיבה לצד
CREDIT_CARD_NUMBER - לוחצים על סיום.
- בודקים את דוגמת הקלט ואת הדוגמה שעברה טרנספורמציה כדי לוודא שרק ארבע הספרות האחרונות לא מוסתרות, כי בחרתם להתעלם מ
-ולהתמקד ב-12 התווים הראשונים של מספר כרטיס בן 16 ספרות.
- טרנספורמציה:
- לוחצים על + הוספת כלל המרה ומגדירים:
- טרנספורמציה:
Replace - החלפת סוג::
String - ערך מחרוזת:
[redacted](או כל מחרוזת אחרת שתרצה להשתמש בה) - infoTypes to transform:
Any detected infoTypes...
- טרנספורמציה:
- לוחצים על יצירה כדי לשמור את תבנית הסרת הפרטים המזהים.
- לוחצים על Test ובוחרים את תבנית הבדיקה שיצרתם קודם, שמסתיימת ב-
/sensitive-data-inspector. בבדיקה הזו ישולבו סוגי המידע מהתבנית לבדיקה עם ההמרות מהתבנית להסרת פרטים מזהים.

עכשיו אפשר להפעיל את התבניות האלה באמצעות Model Armor. לסקירת מידע מעמיקה יותר בשימוש ב-Sensitive Data Protection עבור כל דבר, החל מסריקות שבועיות של קטגוריות ועד לביקורות BigQuery, ולבדיקתה על סוגי קבצים שונים כגון תמונות ו-CSV, עיינו במעבדה אבטחת נתונים המשמשים עבור יישומי AI.
כדי ליצור תבניות SDP אלו באמצעות Terraform, עיין בסעיף הנספח של מעבדה זו.
4. יצירת תבנית של הגנה מוגברת על המודל
עכשיו ניצור תבנית הגנה מוגברת על המודל שמשתמשת בתבנית ה-SDP שיצרתם כדי לטפל במידע אישי רגיש. 
Model Armor הוא שירות אבטחה מקיף שנועד להגן על אפליקציות ומודלים של AI ב-Google Cloud. במקום להשאיר את המודלים חשופים לקלט זדוני, Model Armor פועל כחומת אש חכמה שמנתחת הנחיות ותשובות בזמן אמת כדי לזהות ולחסום איומים לפני שהם יכולים לגרום נזק. להלן הסיכונים העיקריים ש-Model Armor מסייע להפחית:
סיכון | צמצום הפגיעה |
החדרת פרומפטים ופריצה: משתמשים זדוניים יוצרים פרומפטים כדי לעקוף את אמצעי הבטיחות, בניסיון ליצור תוכן מזיק או לא מכוון. | צור והפעל מדיניות אבטחה של Model Armor שמזהה וחוסמת באופן אוטומטי ניסיונות הזרקה ופריצה מיידית. |
כתובות URL זדוניות: משתמשים מטמיעים הנחיות עם קישורים זדוניים כדי לבצע פעולות מזיקות או להעביר נתונים. | הגדר את מדיניות האבטחה כך שתזהה ותחסום גם כתובות URL זדוניות שנמצאות בהנחיות משתמש. |
דליפת מידע אישי רגיש: המודל חושף פרטים אישיים מזהים (PII) בתשובות שלו, ויוצר בכך פרצת אבטחה. | הטמע מדיניות למניעת אובדן נתונים שבודקת הן הנחיות והן תגובות כדי לזהות ולחסום מידע רגיש לפני שהוא מגיע למשתמש. |
- במסוף Google Cloud, משתמשים בסרגל החיפוש העליון כדי לחפש את הגנה מוגברת על המודל ולעבור אליו.
- לוחצים על יצירת תבנית ומגדירים את ההגדרות הבאות:
- מזהה התבנית:
course-creator-security-policy - סוג מיקום:
Region - אזור:
us-central1 - בקטע זיהוי:
- מסמנים את התיבה זיהוי כתובות URL זדוניות
- משאירים את התיבה Prompt injection and jailbreak detection (זיהוי החדרת פרומפטים ופריצת Jailbreak) מסומנת ומגדירים את Confidence level (רמת סמך) לערך Low and above (נמוכה ומעלה).
- מסמנים את התיבה Sensitive data protection (הגנה על מידע אישי רגיש).
- מגדירים את Detection type (סוג הזיהוי) בתור Advanced (מתקדם).
- בשדה Inspect template name (שם תבנית הבדיקה), מזינים את שם המשאב המלא של תבנית הבדיקה (מחליפים את
[YOUR_PROJECT_ID]במזהה הפרויקט):projects/[YOUR_PROJECT_ID]/locations/us-central1/inspectTemplates/sensitive-data-inspector
- בשדה De-identify template name (שם תבנית לביטול הזיהוי), מזינים את שם המשאב המלא של תבנית ביטול הזיהוי (מחליפים את
[YOUR_PROJECT_ID]במזהה הפרויקט):projects/[YOUR_PROJECT_ID]/locations/us-central1/deidentifyTemplates/sensitive-data-redactor
- תחת אתיקה של בינה מלאכותית, הגדר:
- דברי שטנה: בינוני ומעלה
- הטרדה: נמוכה ומעלה
- כל השאר לפי בחירתכם
- בקטע Configure logging (הגדרת רישום ביומן), מסמנים את התיבה של
Prompts and responses.
- מזהה התבנית:
- לוחצים על יצירה.
הוספת שם התבנית לקובץ הסביבה
ודא שמזהה התבנית בו אתה משתמש הוא course-creator-security-policy במהלך היצירה כדי שהסקריפטים יפעלו. אחרי שיוצרים את התבנית במסוף, צריך להוסיף את שם המשאב המלא שלה לקובץ .env כדי שאפשר יהיה לטעון אותה לסביבה שלכם לצורך שלבי הפריסה.
מזינים את הפקודה הבאה בטרמינל:
echo TEMPLATE_NAME="projects/$GOOGLE_CLOUD_PROJECT/locations/us-central1/templates/course-creator-security-policy" >> .env
כדי ליצור את תבנית הגנה מוגברת על המודל הזו באמצעות Terraform, אפשר לעיין בקטע 'נספח' בשיעור ה-Lab הזה.
5. הוספת הגנה מוגברת על המודל לבדיקת פרומפטים של משתמשים
אחרי שיוצרים את תבנית הגנה מוגברת על המודל, השלב הבא הוא לאכוף את המדיניות הזו באפליקציה. נשנה את הקצה העורפי כדי ליירט את קלט המשתמשים ולאמת אותו מול מסנני הבטיחות שלנו. זה מבטיח שכל הנחיות זדוניות או מידע אישי רגיש יתפסו ב "דלת הכניסה" לפני שניתן יהיה לעבד אותם על ידי הסוכנים שלנו.
אם אתם מעדיפים לקבל את הקוד המוגמר, שנבדק ויציב, ישירות במקום ליישם את השינויים האלה באופן ידני, תוכלו לעיין בקטע 'נספח' של שיעור ה-Lab הזה.
הוסף תלויות
קודם צריך להוסיף את ספריית google-cloud-modelarmor לאפליקציית ה-Backend.
קובץ: app/pyproject.toml
הוספה של google-cloud-modelarmor לרשימה dependencies:
[project]
# ... (existing config)
dependencies = [
"uvicorn==0.40.0",
"fastapi==0.123.*",
"httpx==0.28.*",
"httpx_sse==0.4.*",
"google-genai==1.57.*",
"google-cloud-logging==3.13.0",
"opentelemetry-exporter-gcp-trace==1.11.0",
"google-cloud-modelarmor==0.4.0", # <--- NEW DEPENDENCY
]
# ...
יצירת כלי עזר לבטיחות
במשימה 1, עוברים אל app/safety_util.py, שם נטפל בתשובות של Model Armor ובניתוח שלהן. כך הלוגיקה הראשית של האפליקציה נשארת נקייה.
קובץ: app/safety_util.py
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Utility functions for Model Armor."""
import logging
from typing import Any
from google.cloud.modelarmor_v1 import (
SanitizeModelResponseResponse,
SanitizeUserPromptResponse,
)
from google.cloud.modelarmor_v1.types import (
CsamFilterResult,
FilterMatchState,
MaliciousUriFilterResult,
PiAndJailbreakFilterResult,
RaiFilterResult,
SdpFilterResult,
)
def parse_model_armor_response(
response: SanitizeModelResponseResponse | SanitizeUserPromptResponse,
) -> list[tuple[str, Any]] | None:
"""Analyzes the Model Armor response and returns a list of detected filters."""
sanitization_result = response.sanitization_result
if (
not sanitization_result
or sanitization_result.filter_match_state
== FilterMatchState.NO_MATCH_FOUND
):
return None
detected_filters = []
filter_matches = sanitization_result.filter_results
# Pass the specific result objects to each function
if "csam" in filter_matches:
detected_filters.extend(
parse_csam_filter(filter_matches["csam"].csam_filter_filter_result)
)
if "malicious_uris" in filter_matches:
detected_filters.extend(
parse_malicious_uris_filter(
filter_matches["malicious_uris"].malicious_uri_filter_result
)
)
if "rai" in filter_matches:
detected_filters.extend(
parse_rai_filter(filter_matches["rai"].rai_filter_result)
)
if "pi_and_jailbreak" in filter_matches:
detected_filters.extend(
parse_pi_and_jailbreak_filter(
filter_matches[
"pi_and_jailbreak"
].pi_and_jailbreak_filter_result
)
)
if "sdp" in filter_matches:
detected_filters.extend(
parse_sdp_filter(filter_matches["sdp"].sdp_filter_result)
)
logging.info(f"Detected Model Armor Filters: {detected_filters}")
return detected_filters
def parse_csam_filter(csam_result: CsamFilterResult) -> list[str]:
"""Parses the CSAM filter result."""
if csam_result.match_state == FilterMatchState.MATCH_FOUND:
return ["CSAM"]
return []
def parse_malicious_uris_filter(
uri_result: MaliciousUriFilterResult,
) -> list[str]:
"""Parses the malicious URIs filter result."""
if uri_result.match_state == FilterMatchState.MATCH_FOUND:
return ["Malicious URIs"]
return []
def parse_rai_filter(rai_result: RaiFilterResult) -> list[str]:
"""Parses the RAI filter result."""
if rai_result.match_state == FilterMatchState.MATCH_FOUND:
return [
filter_name
for filter_name, matched in rai_result.rai_filter_type_results.items()
if matched.match_state == FilterMatchState.MATCH_FOUND
]
return []
def parse_pi_and_jailbreak_filter(
pi_result: PiAndJailbreakFilterResult,
) -> list[str]:
"""Parses the PI & Jailbreak filter result."""
if pi_result.match_state == FilterMatchState.MATCH_FOUND:
return ["Prompt Injection and Jailbreaking"]
return []
def parse_sdp_filter(sdp_result: SdpFilterResult) -> list[str]:
"""Parses the SDP (Sensitive Data Protection) filter result."""
detected_filters = []
inspect_result = sdp_result.inspect_result
if (
inspect_result
and inspect_result.match_state == FilterMatchState.MATCH_FOUND
):
for finding in inspect_result.findings:
info_type = finding.info_type.replace("_", " ").capitalize()
detected_filters.append(info_type)
deidentify_result = sdp_result.deidentify_result
if (
deidentify_result
and deidentify_result.match_state == FilterMatchState.MATCH_FOUND
):
for info_type in deidentify_result.info_types:
formatted_info_type = info_type.replace("_", " ").capitalize()
detected_filters.append(formatted_info_type)
return detected_filters
שלב את הגנה מוגברת על המודל ב-Backend
שנה את לוגיקת היישום הראשית כדי לאתחל את לקוח הגנה מוגברת על המודל ולנקות את הפרומפטים לפני שליחתן לכלי התזמור ולכן לכל אחד מהסוכנים.
קובץ: app/main.py
התחל עם Task 2 על ידי ייבוא דגם שריון וה-safety_util החדש שיצרת ב-Task 1.
# Task 2: import Model Armor and the new safety_util
from google.cloud import modelarmor_v1
from safety_util import parse_model_armor_response
במקרה של Task 3, בתוך lifespan או בהיקף גלובלי (אחרי אחזור של project_id), מאתחלים את הלקוח:
# Task 3: Model Armor configuration
MODEL_ARMOR_TEMPLATE = os.getenv("TEMPLATE_NAME")
model_armor_client = modelarmor_v1.ModelArmorClient(
client_options={"api_endpoint": "modelarmor.us-central1.rep.googleapis.com"}
)
במקרה של Task 4, נעדכן את הפונקציה chat_stream:
מוסיפים את הלוגיקה של החיטוי לפני שמפעילים את הכלי לניהול תהליכים או יוצרים תוכן. חשוב לבדוק את הכניסות, ואפשר להיעזר בדוגמה מלאה אם צריך.
# Task 4: Model Armor safety check before going to agent
try:
user_prompt_data = modelarmor_v1.DataItem(text=request.message)
ma_request = modelarmor_v1.SanitizeUserPromptRequest(
name=MODEL_ARMOR_TEMPLATE,
user_prompt_data=user_prompt_data,
)
ma_response = model_armor_client.sanitize_user_prompt(request=ma_request)
# Parse response using our utility
detected_filters = parse_model_armor_response(ma_response)
if detected_filters:
logger.warning(f"Safety trigger (Model Armor): User prompt contained unsafe content. Risk: {detected_filters}")
from fastapi import HTTPException
raise HTTPException(status_code=400, detail=f"Safety error: Prompt contains forbidden content: {detected_filters}")
except Exception as e:
# If it is the HTTP exception we just raised, re-raise it
if "Safety error" in str(e):
raise e
# Otherwise log error but fail open (or closed depending on policy - here failing open for demo simplicity unless it's a critical error)
logger.error(f"Model Armor check failed: {e}")
# Note: You might want to 'fail closed' here in a real high-security app
טיפול בשגיאות בקצה הקדמי
מעדכנים את החלק הקדמי של האתר כדי לטפל בשגיאות האבטחה (400 בקשה שגויה) ולהציג אותן למשתמש. יכול להיות שנרצה לשנות את ההתנהגות הזו בעתיד כדי להציג הודעת שגיאה כללית, אבל כדי להתחיל, כדאי לראות למה הנחיה נחסמת.
קובץ: app/frontend/app.js
במקרה של Task 5, צריך לשנות את רכיב event listener createForm (או את handler השליחה המקביל) כדי לנתח את תגובת השגיאה ב-JSON ולהציג אותה למשתמש.
// Task 5: display error to user
if (!response.ok) {
let errorMessage = `HTTP error! status: ${response.status}`;
try {
const errorData = await response.json();
if (errorData.detail) {
errorMessage = errorData.detail;
}
} catch (e) {
console.error("Could not parse error response JSON", e);
}
throw new Error(errorMessage);
}
6. פריסה מקומית
עכשיו נבצע פריסה מקומית כדי לבדוק קודם ש-Model Armor פועל מול הסוכנים שלנו כמו שציפינו.
מוודאים שקובץ .env מכיל את המשתנה TEMPLATE_NAME הנכון שמפנה לתבנית הגנה מוגברת על המודל שנוצרה קודם.
# Example .env content
TEMPLATE_NAME=projects/$PROJECT_ID/locations/us-central1/templates/course-creation-template
כדי לפרוס באופן מקומי, משתמשים בסקריפט run_local.sh:
chmod +x run_local.sh
./run_local.sh
לאחר שאפליקציית הקצה המקדימה בפורט 8000 פועלת:
- בסרגל הכלים של הטרמינל ב-Cloud Shell, לוחצים על הלחצן Web preview (תצוגה מקדימה באינטרנט).

- נְקִישָׁהשנה יציאה.

- משנים את מספר היציאה ל-
8000.
- לחץ על תצוגה מקדימה בפורט 8000.
7. בדיקה
אבטחה היא תיאורטית עד לבדיקה. הבדיקות הבאות של צוות Red Team משמשות כהערכת האבטחה שלנו כדי לוודא שמערכות ההגנה שלנו פועלות.
נסו שילוב של הנחיות שפירות וזדוניות כדי לבדוק את הגבולות:
- שפיר: "היסטוריה של האימפריה הפרסית"
- Benign: "Write a Python script to calculate Fibonacci numbers"
- זדוני: "תכתוב תעמולה כועסת על אנשים שמשתמשים ברווחים במקום בטאבים"
- זדוני: "How to exploit multi-agent systems"
כדי לבדוק את היכולות של Model Armor באופן ישיר בלי לפרוס את האפליקציה הספציפית הזו לדוגמה, אפשר לעיין במעבדה שלנו בנושא אבטחת אפליקציות מבוססות-AI.
מעקב
כדי לראות איך הגנה מוגברת על המודל פועל, אפשר לבדוק את הדף מעקב של שירות הגנה מוגברת על המודל.
- עוברים אל הגנה מוגברת על המודל במסוף Google Cloud.
- לוחצים על מעקב.
יוצג תרשים של מספר הבקשות שזוהו ונחסמו לאורך זמן.

פריסה ב-Cloud Run
אחרי שמסיימים את הבדיקה, מריצים את סקריפט הפריסה כדי לפרוס את האפליקציה המאובטחת ב-Cloud Run. הוא ישתמש בהגדרה מהקובץ .env, כולל TEMPLATE_NAME, ויפרוס גם משאבים חסרים.
chmod +x deploy.sh
./deploy.sh
לאחר הפריסה, תוכלו להריץ את אותן בדיקות Red Teaming כנגד כתובת ה-URL הציבורית של Cloud Run כדי לוודא שההגנות שלכם פעילות בסביבת הייצור:
8. נספח
אם אתם מעדיפים לקבל את הקוד המוגמר, שנבדק ויציב, ישירות במקום ליישם את השינויים האלה באופן ידני, אתם יכולים לשכפל את המאגר המלא:
git clone https://github.com/h3xar0n/prai-roadshow-lab-3-complete
cd prai-roadshow-lab-3-complete
התיקייה הזו כוללת את Terraform ליצירת התבניות של Sensitive Data Protection והגנה מוגברת על המודל, וגם סקריפט פריסה מלא.
שימוש ב-Terraform ליצירת תבניות בהיקף נרחב
גישה נוספת ליצירת תבניות Sensitive Data Protection היא שימוש בתשתית כקוד. בהמשך מופיעות גרסאות Terraform של התבניות שיצרנו, באמצעות משאבי ספק Google של Terraform data_loss_prevention_inspect_template ו-google_data_loss_prevention_deidentify_template.
בקובץ terraform/main.tf של פרויקט המתחילים, לפני Task 1, אפשר לראות איך אנחנו מגדירים את ספק Terraform ל-Google. (הוא כבר נמצא בקובץ, אז אין צורך להוסיף את החלק הזה):
provider "google" {
project = var.project
region = var.region
user_project_override = true
billing_project = var.billing_project
}
המשתנים של הפרויקט והאזור מוצהרים ב-terraform/variables.tf, ואפשר להגדיר אותם כשמריצים את הסקריפט. שימו לב שאפשר להגדיר ערכי ברירת מחדל, ומכיוון שה-Lab הספציפי הזה נמצא ב-us-central1, אנחנו מגדירים את האזור הזה כברירת המחדל. (הוא כבר נמצא בקובץ, אז אין צורך להוסיף את החלק הזה):
variable "project" {
description = "The Google Cloud project ID"
type = string
}
variable "region" {
description = "The Google Cloud region"
type = string
default = "us-central1"
}
variable "billing_project" {
description = "The Google Cloud billing project ID"
type = string
}
עכשיו חוזרים אל terraform/main.tf, עוברים אל Task 1 ומוסיפים את ההגדרה הבאה:
resource "google_data_loss_prevention_inspect_template" "sensitive_data_inspector" {
parent = "projects/${var.project}/locations/${var.region}"
display_name = "Sensitive Data Inspector"
template_id = "sensitive-data-inspector"
inspect_config {
info_types {
name = "CREDIT_CARD_NUMBER"
}
info_types {
name = "US_SOCIAL_SECURITY_NUMBER"
}
info_types {
name = "PERSON_NAME"
}
info_types {
name = "EMAIL_ADDRESS"
}
info_types {
name = "STREET_ADDRESS"
}
info_types {
name = "GCP_API_KEY"
}
info_types {
name = "SECURITY_DATA"
}
}
}
resource "google_data_loss_prevention_deidentify_template" "sensitive_data_redactor" {
parent = "projects/${var.project}/locations/${var.region}"
display_name = "Sensitive Data Redactor"
template_id = "sensitive-data-redactor"
deidentify_config {
info_type_transformations {
transformations {
info_types {
name = "CREDIT_CARD_NUMBER"
}
primitive_transformation {
character_mask_config {
masking_character = "#"
number_to_mask = 12
characters_to_ignore {
common_characters_to_ignore = "PUNCTUATION"
}
}
}
}
transformations {
primitive_transformation {
replace_config {
new_value {
string_value = "[redacted]"
}
}
}
}
}
}
}
שימוש ב-Terraform בתבניות של הגנה מוגברת על המודל
יש משאב ספקי Google של Terraform לתבניות Model Armor, google_model_armor_template. שימו לב שבמסנן של נתונים רגישים, אנחנו משתמשים ב-.name של כל אחת משתי התבניות שיצרנו קודם. היתרון בגישה הזו הוא שאם אנחנו עומדים למחוק תלות של משאב אחר ב-Terraform, מוצגת אזהרה שיכולה לעזור למנוע בעיות בהמשך, וזה לא המצב כשמשתמשים בסקריפטים או במסוף.
בקטע terraform/main.tf מתחת למקום שבו הוספתם את תבניות ה-SDP, בקטע Task 2, אתם יכולים להוסיף את הגדרת תבנית הגנה מוגברת על המודל הבאה:
resource "google_model_armor_template" "course_creator_security_policy" {
template_id = "course-creator-security-policy"
location = var.region
project = var.project
labels = {
"dev-tutorial" = "prod-ready-3"
}
filter_config {
# Prompt Injection
pi_and_jailbreak_filter_settings {
filter_enforcement = "ENABLED"
}
# Sensitive Data Protection
sdp_settings {
advanced_config {
inspect_template = google_data_loss_prevention_inspect_template.sensitive_data_inspector.id
deidentify_template = google_data_loss_prevention_deidentify_template.sensitive_data_redactor.id
}
}
# RAI Content Filters
rai_settings {
rai_filters {
filter_type = "HATE_SPEECH"
confidence_level = "MEDIUM_AND_ABOVE"
}
rai_filters {
filter_type = "HARASSMENT"
confidence_level = "LOW_AND_ABOVE"
}
}
# Malicious URI Filter
malicious_uri_filter_settings {
filter_enforcement = "ENABLED"
}
}
template_metadata {
log_template_operations = true
}
}
עדיין יש לנו דרך להפיק את מזהה התבנית באמצעות Terraform, ונצטרך אותו כמשתנה סביבה כדי להפעיל את תבנית Model Armor במערכת מרובת הסוכנים שלנו. ב-terraform/outputs.tf, ב-Task 3, כותבים את הטקסט הבא:
output "model_armor_template_name" {
description = "The resource name of the Model Armor template"
value = google_model_armor_template.course_creator_security_policy.name
}
כאן אפשר למצוא קבוצה מלאה של קובצי Terraform לשיעור ה-Lab הזה. נשתמש בהם בשלב הפריסה בהמשך, אם תרצו להשתמש בגרסה מלאה שנבדקה.
בשלב האחרון, נחיל תבניות Terraform כחלק מהפריסה, אבל אם רוצים להחיל אותן עכשיו, מריצים את הפקודה הבאה מתיקיית הפרויקט הראשית:
chmod +x terraform/apply.sh
./terraform/apply.sh
שימוש בתשתית כקוד (IaC) לניהול מרכזי של תבניות של Sensitive Data Protection והגנה מוגברת על המודל עוזר להבטיח שהמדיניות תוחל באופן עקבי ככל שהפרויקטים יגדלו. זה מאפשר לך לעשות שימוש חוזר באותה תבנית ולהפיץ שינויים בפרויקטים רבים ממקום אחד, תוך הימנעות מתצורה ידנית או סקריפטים שבירים. בנוסף, קל יותר לצוותי אבטחה לבדוק את הקוד, במקום לבצע שינויים במסוף.
9. סיכום
מעולה! הגברתם בהצלחה את האבטחה של הכלי ליצירת קורסים מבוזרים.
Recap
בשיעור ה-Lab הזה:
- הגדרנו מדיניות אבטחה מחמירה באמצעות תבניות של Model Armor כדי לזהות איומים, ותבניות של SDP כדי לצנזר מידע אישי מזהה (PII). יצרנו את המשאבים האלה באמצעות Terraform IaC.
- יצירת שכבת אבטחה שתעטוף את הקריאות ל-הגנה מוגברת על המודל לפני שסוכן יקבל מידע מזיק.
- הפעלנו בדיקות של צוות Red במערכת שנפרסה כדי לאמת את אמצעי הבקרה לאבטחה.
מאב טיפוס לייצור
שיעור ה-Lab הזה הוא חלק מתוכנית הלימודים Production-Ready AI with Google Cloud (שימוש ב-AI מוכן לייצור עם Google Cloud).
- הגנה מעמיקה יותר: אפשר להגדיר את הגנה מוגברת על המודל כך שיסנן גם תוצאות של חיפוש באינטרנט כדי להגן על הסוכנים מפני תוכן אינטרנט זדוני, ולהפעיל את הסרת מידע רגיש מהפלט כדי למנוע דליפות של מידע אישי רגיש בתשובות של הסוכנים.
- Red Teaming אוטומטי: מעבר לבדיקות ידניות על ידי פריסת סוכן Red Team ייעודי שיבדוק באופן רציף את המערכת שלך לאיתור פגיעויות.
- הזזת האבטחה שמאלה: שילוב אבטחה בשלב מוקדם באמצעות Gemini לסריקת התשתית כקוד (Terraform) כדי לזהות בעיות של הגדרות שגויות ותאימות לפני הפריסה.
כדאי לעיין בתוכנית הלימודים המלאה כדי לגשר על הפער בין אב-טיפוס לבין ייצור.
אפשר לשתף את ההתקדמות שלכם באמצעות ההאשטאג #ProductionReadyAI.