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

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

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

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

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

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

2. הגדרת משאבי ענן

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

  • משכפלים את המאגר הזה באמצעות הפקודה שלמטה כדי לקבל את הסקריפטים הנדרשים שמשמשים כחלק מה-codelab הזה.
git clone https://github.com/GoogleCloudPlatform/confidential-space.git
  • שינוי הספרייה של ה-codelab הזה.
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, שכולל את תנאי ההרשאה לשימוש באסימונים שנחתמו על ידי שירות אימות הזהות.

$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

שם מכונת ה-VM של עומס העבודה.

$WORKLOAD_IMAGE_NAME

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

$WORKLOAD_IMAGE_TAG

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

$WORKLOAD_SERVICEACCOUNT

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

$CLIENT_VM

השם של מכונת ה-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), לקריאת נתונים מהקטגוריה של Cloud Storage (באמצעות התפקיד 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.

בבקשה ליצירת קוד, עומס העבודה יקבל את מפתח ה-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 שמשמש להצפנת הנחיות, על סמך מאפיינים של המשאבים הבאים:

  • מה: קוד שאומת
  • איפה: בסביבה מאובטחת
  • מי: אופרטור מהימן

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

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

  • מה: הגרסה האחרונה של $WORKLOAD_IMAGE_NAME הועלתה למאגר $PRIMUS_ARTIFACT_REPOSITORY.
  • איפה: סביבת המחשוב האמינה של Confidential Space פועלת בתמונה של מכונה וירטואלית של Confidential Space עם תמיכה מלאה.
  • מי: חשבון השירות של Primus $WORKLOAD_SERVICE_ACCOUNT.
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. בנוסף, הוא כולל טענות ספציפיות לעומס העבודה, כמו image_digest ו-image_reference, כדי לשפר את האבטחה ולהבטיח את השלמות של עומס העבודה הפועל.

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

כחלק מהשלב הזה, נריץ את עומס העבודה במכונה הווירטואלית של Trusted Space, שיהיה לה מצורף מאיץ. ארגומנטים נדרשים של TEE מועברים באמצעות הדגל של המטא נתונים. הארגומנטים של קונטיינר עומס העבודה מועברים באמצעות החלק tee-cmd של הדגל. כדי לצייד את מכונת ה-VM של עומס העבודה ב-GPU מסוג Nvidia Tesla T4, נשתמש בדגל --accelerator=type=nvidia-tesla-t4,count=1. הפעולה הזו תצרף GPU אחד ל-VM. בנוסף, נצטרך לכלול את 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 יכולים לשלוח בקשות ליצירת קוד לשרת להסקת מסקנות.

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

./setup_client.sh

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

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

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

source venv/bin/activate
python3 inference_client.py

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

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 Console.
  • בוחרים את הפרויקט שרוצים לסגור ולוחצים על 'מחיקה' בחלק העליון. הפעולה הזו מתזמנת את הפרויקט למחיקה.