Codelab בנושא Trusted Space

1. סקירה כללית

רוצים לשפר את האבטחה והפרטיות של עומסי העבודה שמואצים על ידי GPU? ב-codelab הזה נסביר על היכולות של Trusted Space, חבילה שמספקת בידוד חזק של מפעילים ותמיכה במאיצים לעומסי עבודה רגישים של AI/ML.

הגנה על נתונים, מודלים ומפתחות חשובים היא קריטית יותר מתמיד. Trusted Space מציע פתרון שמבטיח שעומסי העבודה פועלים בסביבה מאובטחת ואמינה, שבה גם למפעיל של עומס העבודה אין גישה.

מה כולל המרחב המאובטח:

  • פרטיות ואבטחה משופרות: Trusted Space מספק סביבה מאובטחת לביצוע קוד, שבה הנכסים הרגישים (למשל, מודלים, נתונים חשובים ומפתחות) מוגנים ומגובים בהוכחה קריפטוגרפית.
  • בידוד של מפעילים: ביטול החששות לגבי התערבות של מפעילים. ב-Trusted Space, גם למפעילי עומסי העבודה אין גישה, כך שהם לא יכולים להשתמש ב-SSH, לגשת לנתונים, להתקין תוכנה או לשבש את הקוד.
  • תמיכה במאיצי חומרה: Trusted Space תוכנן לפעול בצורה חלקה עם מגוון רחב של מאיצי חומרה, כולל מעבדי GPU כמו H100,‏ A100,‏ T4 ו-L4. כך תוכלו לוודא שאפליקציות ה-AI/ML הקריטיות לביצועים יפעלו בצורה חלקה.

מה תלמדו

  • הסבר על המוצרים העיקריים של Trusted Space.
  • איך לפרוס ולהגדיר סביבה של Trusted Space כדי לאבטח נכסים חשובים של עומסי העבודה של AI/ML.

מה צריך להכין

הגנה על הנחיות ליצירת קוד רגיש באמצעות Primus Company

בקודלאב הזה נכנס לנעליים של Primus, חברה שמתמקדת בשמירה על הפרטיות והאבטחה של נתוני העובדים שלה. ב-Primus רוצים לפרוס מודל ליצירת קוד כדי לעזור למפתחים שלהם במשימות הקוד שלהם. עם זאת, הם מודאגים לגבי הגנה על הסודיות של ההנחיות שהעובדים שלהם שולחים, כי ההנחיות האלה מכילות לרוב קטעי קוד רגישים, פרטי פרויקטים פנימיים או אלגוריתמים קנייניים.

למה חברת Primus לא סומכת על המפעיל?

Primus Corp פועלת בשוק תחרותי מאוד. קוד המקור שלהם מכיל קניין רוחני יקר, כולל אלגוריתמים קנייניים וקטעי קוד רגישים שמספקים יתרון תחרותי. הם חוששים מאפשרות של ריגול עסקי על ידי מפעילי עומסי עבודה. בנוסף, הנחיות לעובדים עשויות לכלול חלקים סודיים של קוד ש-Primus Corp רוצה להגן עליהם, והם זמינים רק לעובדים שיש להם צורך לדעת.

כדי לטפל בבעיה הזו, Primus Corp תשתמש ב-Trusted Space כדי לבודד את שרת ההסקה שבו פועל המודל ליצירת קוד. ככה זה עובד:

  • הצפנת הנחיה: לפני שליחת הנחיה לשרת ההסקה, כל עובד יהיה צריך להצפין אותה באמצעות מפתח KMS שמנוהל על ידי Primus Corp ב-Google Cloud. כך מובטח שרק סביבת Trusted Space, שבה מפתח הפענוח המתאים זמין, יכולה לפענח אותו ולגשת להנחיה בטקסט ללא הצפנה. בתרחיש בעולם האמיתי, הספריות הזמינות יכולות לטפל בהצפנה מצד הלקוח (למשל tink). כחלק מהקודלאב הזה, נשתמש באפליקציית הלקוח לדוגמה הזו עם הצפנת מעטפה.
  • בידוד של המפעיל: רק לשרת ההסקה, שפועל בסביבת Trusted Space, תהיה גישה למפתח שמשמש להצפנה, והוא יוכל לפענח את ההנחיה בסביבה מהימנה. הגישה למפתח ההצפנה תהיה מוגנת על ידי מאגר הזהויות של כוח העבודה. בזכות ההתחייבות לבידוד של Trusted Space, גם למפעיל עומס העבודה אין גישה למפתח שמשמש להצפנה ולתוכן המוצפן.
  • הסקת מסקנות מאובטחת באמצעות מאיצים: שרת ההסקה יופעל במכונה וירטואלית מוגנת (כחלק מהגדרת Trusted Space), כדי להבטיח שמכונה של עומס העבודה לא נפרצה על ידי תוכנה זדונית או rootkit ברמת האתחול או הליבה. השרת הזה מפענח את ההנחיה בסביבת Trusted Space, מבצע את ההסקה באמצעות מודל היצירה של הקוד ומחזיר את הקוד שנוצר לעובד.

2. הגדרת משאבי Cloud

לפני שמתחילים

  • כדי לקבל את הסקריפטים הנדרשים שנעשה בהם שימוש במסגרת הקודלאב הזה, צריך ליצור עותק (clone) של המאגר הזה באמצעות הפקודה הבאה.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • שינוי הספרייה של סדנת הקוד הזו.
cd confidential-space/codelabs/trusted_space_codelab/scripts
  • חשוב לוודא שהגדרתם את משתני הסביבה הנדרשים של הפרויקט, כפי שמתואר בהמשך. מידע נוסף על הגדרת פרויקט ב-GCP זמין בקודלאב הזה. כאן מוסבר איך לאחזר את מזהה הפרויקט ואיך הוא שונה משם הפרויקט וממספר הפרויקט.
export PRIMUS_PROJECT_ID=<GCP project id of Primus>
  • מפעילים את החיוב בפרויקטים.
  • מפעילים את Confidential Computing API ואת ממשקי ה-API הבאים בשני הפרויקטים.
gcloud services enable \
    cloudapis.googleapis.com \
    cloudresourcemanager.googleapis.com \
    cloudkms.googleapis.com \
    cloudshell.googleapis.com \
    container.googleapis.com \
    containerregistry.googleapis.com \
    iam.googleapis.com \
    confidentialcomputing.googleapis.com
  • מקצים ערכים למשתנים של שמות המשאבים שצוינו למעלה באמצעות הפקודה הבאה. המשתנים האלה מאפשרים לכם להתאים אישית את שמות המשאבים לפי הצורך, וגם להשתמש במשאבים קיימים אם הם כבר נוצרו. (למשל export PRIMUS_SERVICE_ACCOUNT='my-service-account')
  1. אפשר להגדיר את המשתנים הבאים עם שמות של משאבים קיימים בענן בפרויקט Primus. אם המשתנה מוגדר, המערכת תשתמש במשאב הענן הקיים המתאים מהפרויקט Primus. אם המשתנה לא מוגדר, שם המשאב בענן ייווצר מהשם של הפרויקט וייווצר משאב חדש בענן בשם הזה. אלה המשתנים הנתמכים לשמות המשאבים:

$PRIMUS_PROJECT_REGION

האזור שבו ייוצרו משאבים אזוריים עבור חברת Primus.

$PRIMUS_SERVICE_LOCATION

המיקום שבו המשאבים ייווצרו עבור חברת Primus.

$PRIMUS_PROJECT_ZONE

תחום שבו ייוצרו משאבים של תחום מוגדר עבור חברת Primus.

$PRIMUS_WORKLOAD_IDENTITY_POOL

מאגר הזהויות של כוח העבודה של חברת Primus, שמגן על משאבי הענן.

$PRIMUS_WIP_PROVIDER

ספק מאגר הזהויות של כוח העבודה של חברת Primus, שכולל את תנאי ההרשאה לשימוש באסימונים שנחתמו על ידי שירות אימות האימות (attestation).

$PRIMUS_SERVICEACCOUNT

חשבון השירות של חברת Primus, שבו $PRIMUS_WORKLOAD_IDENTITY_POOL משתמש כדי לגשת למשאבים המוגנים. בשלב הזה, יש לו הרשאה להציג את נתוני הלקוחות שמאוחסנים בקטגוריה $PRIMUS_INPUT_STORAGE_BUCKET.

$PRIMUS_ENC_KEY

מפתח ה-KMS משמש להצפנת ההנחיות שסופקו על ידי העובדים של חברת Primus.

$PRIMUS_ENC_KEYRING

מַפְתח הגיבוי של KMS שישמש ליצירת מפתח ההצפנה $PRIMUS_ENC_KEY לחברת Primus.

$PRIMUS_ENC_KEYVERSION

גרסת מפתח ה-KMS של מפתח ההצפנה $PRIMUS_ENC_KEY. ערך ברירת המחדל הוא 1. צריך לעדכן את השדה הזה אם אתם משתמשים במפתח קיים שעבר רוטציה בעבר והגרסה שלו עודכנה.

$PRIMUS_ARTIFACT_REPOSITORY

מאגר הארטיפקטים שאליו תישלח קובץ האימג' של Docker של עומס העבודה.

$PRIMUS_PROJECT_REPOSITORY_REGION

האזור של מאגר הארטיפקטים שבו תהיה תמונה של Docker של עומס העבודה שפורסם.

$WORKLOAD_VM

השם של מכונה וירטואלית של כוח עבודה.

$WORKLOAD_IMAGE_NAME

השם של קובץ האימג' של Docker של עומס העבודה.

$WORKLOAD_IMAGE_TAG

תג של קובץ האימג' בקונטיינר של עומס העבודה.

$WORKLOAD_SERVICEACCOUNT

חשבון השירות שיש לו הרשאה לגשת למכונה הווירטואלית הסודית שמריצה את עומס העבודה.

$CLIENT_VM

השם של מכונה וירטואלית של לקוח שבה תרוץ אפליקציית הלקוח של שרת ההסקה.

$CLIENT_SERVICEACCOUNT

חשבון השירות שבו משתמש $CLIENT_VM

  • צריכים את התפקידים Storage Admin,‏ Artifact Registry Administrator,‏ Cloud KMS Admin,‏ Service Account Admin ו-IAM Workload Identity Pool Admin בפרויקט $PRIMUS_PROJECT_ID. במדריך הזה מוסבר איך מקצים תפקידים ב-IAM באמצעות מסוף GCP.
  • עבור $PRIMUS_PROJECT_ID, מריצים את הסקריפט הבא כדי להגדיר את שאר שמות המשתנים לערכים שמבוססים על מזהה הפרויקט שלכם לשמות המשאבים.
source config_env.sh

הגדרת משאבים של חברת Primus

בשלב הזה תגדירו את משאבי הענן הנדרשים ל-Primus. מריצים את הסקריפט הבא כדי להגדיר את המשאבים ל-Primus. המשאבים הבאים נוצרים כחלק מהרצת הסקריפט:

  • מפתח הצפנה ($PRIMUS_ENC_KEY) ואוסף מפתחות ($PRIMUS_ENC_KEYRING) ב-KMS להצפנת קובץ נתוני הלקוחות של חברת Primus.
  • מאגר זהויות של כוח עבודה ($PRIMUS_WORKLOAD_IDENTITY_POOL) כדי לאמת הצהרות על סמך תנאי המאפיינים שהוגדרו בספק שלו.
  • לחשבון השירות ($PRIMUS_SERVICE_ACCOUNT) שמצורף למאגר הזהויות של כוח העבודה שצוין למעלה ($PRIMUS_WORKLOAD_IDENTITY_POOL) יש גישה לפענוח נתונים באמצעות מפתח KMS (באמצעות התפקיד roles/cloudkms.cryptoKeyDecrypter), להצפנת נתונים באמצעות מפתח KMS (באמצעות התפקיד roles/cloudkms.cryptoKeyEncrypter), לקריאת נתונים מקטגוריית האחסון בענן (באמצעות התפקיד objectViewer) ולחיבור חשבון השירות למאגר הזהויות של כוח העבודה (באמצעות roles/iam.workloadIdentityUser).
./setup_primus_resources.sh

3. יצירת עומס עבודה

יצירת חשבון שירות של כוח עבודה

עכשיו תיצורו חשבון שירות לעומס העבודה עם התפקידים וההרשאות הנדרשים. מריצים את הסקריפט הבא כדי ליצור חשבון שירות של כוח עבודה בפרויקט Primus. חשבון השירות הזה ישמש את המכונה הווירטואלית שמריצה את שרת ההסקה.

לחשבון השירות של עומס העבודה ($WORKLOAD_SERVICEACCOUNT) יהיו התפקידים הבאים:

  • confidentialcomputing.workloadUser כדי לקבל טוקן אימות
  • logging.logWriter כדי לכתוב יומנים ב-Cloud Logging.
./create_workload_service_account.sh

יצירת עומס עבודה

בשלב הזה, תיצרו קובץ אימג' של Docker של כוח עבודה. עומס העבודה ייווצר על ידי חברת Primus. עומס העבודה שנעשה בו שימוש ב-codelab הזה הוא קוד Python שמשתמש במודל codegemma מקטגוריית GCS שזמינה לכולם (של vertex model garden). עומס העבודה יטען את מודל codegemma ויפעיל את שרת ההסקה, שיציג את הבקשות ליצירת קוד מהמפתחים של Primus.

בבקשה ליצירת קוד, Workload יקבל את ה-DEK המכווץ יחד עם הנחיה מוצפנת. לאחר מכן, עומס העבודה יבצע קריאה ל-KMS API כדי לפענח את ה-DEK, ולאחר מכן יבצע פענוח של ההנחיה באמצעות ה-DEK הזה. מפתחות ההצפנה (של DEK) יהיו מוגנים באמצעות מאגר הזהויות של כוח העבודה, והגישה תוענק לעומסי העבודה שעומדים בתנאי המאפיינים. תנאי המאפיינים האלה מתוארים בפירוט בקטע הבא בנושא הרשאה לעומס העבודה. אחרי ששרת ההסקה יקבל את ההנחיה מפענחת, הוא ייצור את הקוד באמצעות מודל טעון ויחזיר את התגובה.

מריצים את הסקריפט הבא כדי ליצור עומס עבודה שבו מתבצעים השלבים הבאים:

  • יוצרים מאגר Artifact Registry‏($PRIMUS_ARTIFACT_REGISTRY) בבעלות Primus.
  • מעדכנים את קוד עומס העבודה בשמות המשאבים הנדרשים.
  • פיתוח עומס העבודה של שרת ההסקה וליצור קובץ Dockerfile ליצירת קובץ אימג' של Docker של קוד עומס העבודה. כאן מופיע קובץ Dockerfile שמשמש ב-codelab הזה.
  • פיתוח ופרסום של קובץ האימג' של Docker ב-Artifact Registry ($PRIMUS_ARTIFACT_REGISTRY) שבבעלות Primus.
  • מעניקים ל-$WORKLOAD_SERVICEACCOUNT הרשאת קריאה עבור $PRIMUS_ARTIFACT_REGISTRY. הדבר נדרש כדי שקונטיינר עומס העבודה יוכל למשוך את קובץ האימג' של Docker של עומס העבודה מ-Artifact Registry.
./create_workload.sh

לידיעתכם, הנה השיטה generate() של עומס העבודה שנוצר ומשומש בסדנת הקוד הזו (אפשר למצוא את קוד עומס העבודה המלא כאן).

def generate():
  try:
    data = request.get_json()
    ciphertext = base64.b64decode(data["ciphertext"])
    wrapped_dek = base64.b64decode(data["wrapped_dek"])
    unwrapped_dek_response = kms_client.decrypt(
        request={"name": key_name, "ciphertext": wrapped_dek}
    )
    unwrapped_dek = unwrapped_dek_response.plaintext
    f = Fernet(unwrapped_dek)
    plaintext = f.decrypt(ciphertext)
    prompt = plaintext.decode("utf-8")
    tokens = tokenizer(prompt, return_tensors="pt")
    outputs = model.generate(**tokens, max_new_tokens=128)
    generated_code = tokenizer.decode(outputs[0])
    generated_code_bytes = generated_code.encode("utf-8")

    response = f.encrypt(generated_code_bytes)
    ciphertext_base64 = base64.b64encode(response).decode("utf-8")
    response = {"generated_code_ciphertext": ciphertext_base64}
    return jsonify(response)

  except (ValueError, TypeError, KeyError) as e:
    return jsonify({"error": str(e)}), 500

4. מתן הרשאה להפעלת עומס העבודה

מתן הרשאה לעומס עבודה

Primus רוצה להעניק לעומסי עבודה הרשאת גישה למפתח ה-KMS שלהם, המשמש להצפנה מיידית על סמך מאפיינים של המשאבים הבאים:

  • מה: קוד מאומת
  • איפה: סביבה מאובטחת
  • Who: מפעיל מהימן

Primus משתמש באיחוד שירותי אימות הזהות של עומסי עבודה כדי לאכוף מדיניות גישה על סמך הדרישות האלה. איחוד שירותי אימות הזהות של עומסי עבודה מאפשר לציין תנאי מאפיינים. התנאים האלה מגבילים את הזהויות שיכולות לבצע אימות באמצעות מאגר הזהויות של כוח העבודה (WIP). אפשר להוסיף את שירות אימות האימות ל-WIP כספק של מאגר זהויות של כוח עבודה כדי להציג מדידות ולאכוף את המדיניות.

מאגר הזהויות של כוח העבודה כבר נוצר בשלב הקודם, כחלק מהגדרת המשאבים בענן. עכשיו Primus ייצור ספק חדש של מאגר זהויות של כוח עבודה ב-OIDC. הערך שצוין בשדה --attribute-condition מאשר גישה לקונטיינר של עומס העבודה. כדי להשתמש בה צריך:

  • מה: $WORKLOAD_IMAGE_NAME העדכני ביותר שהועלה למאגר $PRIMUS_ARTIFACT_REPOSITORY.
  • איפה: סביבת המחשוב המהימנה של Confidential Space פועלת בתמונה של המכונה הווירטואלית של Confidential Space שנתמכת במלואה.
  • Who: חשבון השירות $WORKLOAD_SERVICE_ACCOUNT של Primus.
export WORKLOAD_IMAGE_DIGEST=$(gcloud artifacts docker images describe ${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG  --format="value(image_summary.digest)" --project ${PRIMUS_PROJECT_ID})
gcloud iam workload-identity-pools providers create-oidc $PRIMUS_WIP_PROVIDER \
  --location="global" \
  --project="$PRIMUS_PROJECT_ID" \
  --workload-identity-pool="$PRIMUS_WORKLOAD_IDENTITY_POOL" \
  --issuer-uri="https://confidentialcomputing.googleapis.com/" \
  --allowed-audiences="https://sts.googleapis.com" \
  --attribute-mapping="google.subject='assertion.sub'" \
  --attribute-condition="assertion.swname == 'HARDENED_SHIELDED' && assertion.hwmodel == 'GCP_SHIELDED_VM' && 
assertion.submods.container.image_digest == '${WORKLOAD_IMAGE_DIGEST}' &&
 assertion.submods.container.image_reference == '${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/$PRIMUS_PROJECT_ID/$PRIMUS_ARTIFACT_REPOSITORY/$WORKLOAD_IMAGE_NAME:$WORKLOAD_IMAGE_TAG' && 
'$WORKLOAD_SERVICEACCOUNT@$PRIMUS_PROJECT_ID.iam.gserviceaccount.com' in assertion.google_service_accounts"

הפקודה שלמעלה מאמתת שעומס העבודה פועל בסביבת מרחב מהימן, על ידי בדיקה שהערך של hwmodel מוגדר כ-GCP_SHIELDED_VM והערך של swname מוגדר כ-HARDENED_SHIELDED. בנוסף, הוא כולל טענות נכוֹנוּת (assertions) ספציפיות לעומס העבודה, כמו image_digest ו-image_reference, כדי לשפר את האבטחה ולהבטיח את השלמות של עומס העבודה שפועל.

הפעלת עומס עבודה

כחלק מהשלב הזה, נריץ את עומס העבודה במכונה הווירטואלית של Trusted Space, שתהיה מחוברת למאיץ. מעבירים את הארגומנטים הנדרשים ל-TEE באמצעות דגל המטא-נתונים. הארגומנטים של קונטיינר עומס העבודה מועברים באמצעות החלק tee-cmd של הדגל. כדי לצייד את המכונה הווירטואלית של עומס העבודה ב-GPU של Nvidia Tesla T4, נשתמש בדגל --accelerator=type=nvidia-tesla-t4,count=1. הפקודה הזו תצרף GPU אחד למכונה הווירטואלית. נצטרך גם לכלול את tee-install-gpu-driver=true בדגלים של המטא-נתונים כדי להפעיל את התקנת מנהל ה-GPU המתאים.

gcloud compute instances create ${WORKLOAD_VM} \
  --accelerator=type=nvidia-tesla-t4,count=1 \
  --machine-type=n1-standard-16 \
  --shielded-secure-boot \
  --image-project=conf-space-images-preview \
  --image=confidential-space-0-gpupreview-796705b \
  --zone=${PRIMUS_PROJECT_ZONE} \
  --maintenance-policy=TERMINATE \
  --boot-disk-size=40 \
  --scopes=cloud-platform \
  --service-account=${WORKLOAD_SERVICEACCOUNT}@${PRIMUS_PROJECT_ID}.iam.gserviceaccount.com \
  --metadata="^~^tee-image-reference=${PRIMUS_PROJECT_REPOSITORY_REGION}-docker.pkg.dev/${PRIMUS_PROJECT_ID}/${PRIMUS_ARTIFACT_REPOSITORY}/${WORKLOAD_IMAGE_NAME}:${WORKLOAD_IMAGE_TAG}~tee-install-gpu-driver=true~tee-restart-policy=Never"

הרצת שאילתה של הסקת מסקנות

אחרי ההפעלה המוצלחת של שרת ההסקה של עומסי העבודה, העובדים של חברת Primus יכולים לשלוח את הבקשות ליצירת קוד לשרת ההסקה.

כחלק מהקודלאב הזה, נשתמש בסקריפט הבא כדי להגדיר את אפליקציית הלקוח שתהיה באינטראקציה עם שרת ההסקה. מריצים את הסקריפט הזה כדי להגדיר את המכונה הווירטואלית של הלקוח.

./setup_client.sh

בשלבים הבאים מוסבר איך להתחבר ב-SSH למכונה הווירטואלית של הלקוח ולהריץ אפליקציית לקוח לדוגמה בסביבה וירטואלית של Python. באפליקציה לדוגמה הזו נעשה שימוש בהצפנת מעטפה באמצעות ספריית Fernet, אבל חשוב לזכור שאפשר להתאים את ספריות ההצפנה הספציפיות למקרים שונים של שימוש.

gcloud compute ssh ${CLIENT_VM} --zone=${PRIMUS_PROJECT_ZONE}

מריצים את הפקודות הבאות כדי להפעיל את הסביבה הווירטואלית של Python במכונת ה-VM של הלקוח ולהריץ את אפליקציית הלקוח.

source venv/bin/activate
python3 inference_client.py

הפלט של אפליקציית הלקוח לדוגמה הזו יציג את בקשות ההצפנה וההנחיה ל-plaintext, ואת התשובות המקבילות להן לאחר הצפנה ופענוח.

5. הסרת המשאבים

כאן מופיע הסקריפט שאפשר להשתמש בו כדי לנקות את המשאבים שיצרנו במסגרת ה-Codelab הזה. במסגרת הניקוי, המשאבים הבאים יימחקו:

  • חשבון השירות של Primus ($PRIMUS_SERVICEACCOUNT).
  • מפתח ההצפנה של Primus ($PRIMUS_ENC_KEY).
  • מאגר פריטי מידע שנוצרו בתהליך פיתוח (Artifact) של Primus‏ ($PRIMUS_ARTIFACT_REPOSITORY).
  • מאגר הזהויות של כוח העבודה ב-Primus‏ ($PRIMUS_WORKLOAD_IDENTITY_POOL) עם הספק שלו.
  • חשבון השירות של כוח העבודה של Primus‏ ($WORKLOAD_SERVICEACCOUNT).
  • מכונה וירטואלית של כוח עבודה ($WORKLOAD_VM) ומכונה וירטואלית של לקוח ($CLIENT_VM).
./cleanup.sh

אם סיימתם לבדוק את הנתונים, כדאי למחוק את הפרויקט.

  • נכנסים למסוף Cloud Platform.
  • בוחרים את הפרויקט שרוצים להשבית ולוחצים על 'Delete' בחלק העליון: הפעולה הזו תזמן את המחיקה של הפרויקט.