בדף הזה מוסבר איך ליצור את מקורות המידע של הבנייה, להציג את הפלט ולאמת אותו.
אישור המקור של Build הוא אוסף של נתונים שניתנים לאימות לגבי build. מטא-נתוני המקור כוללים פרטים כמו תקצירי התמונות שנוצרו, מיקומי מקורות הקלט, ארגומנטים של הבנייה ומשך הבנייה. אתם יכולים להשתמש במידע הזה כדי לוודא שהארטיפקטים שאתם משתמשים בהם מדויקים ואמינים, ונוצרו על ידי מקורות ובוני מהימנים.
Cloud Build תומך ביצירת אישור המקור של Build שעומדים בדרישות של רמת אבטחה 3 של רמות של שרשרת אספקה לארטיפקטים של תוכנה (SLSA) על סמך המפרטים של SLSA בגרסה 0.1 ובגרסה 1.0.
במסגרת התמיכה במפרט SLSA v1.0, Cloud Build מספק פרטים על buildType באישור המקור של Build. אתם יכולים להשתמש בסכימה buildType כדי להבין את התבנית עם הפרמטרים שמשמשת לתהליך הבנייה, כולל הערכים שמתועדים ב-Cloud Build והמקור של הערכים האלה.
מידע נוסף זמין במאמר בנושא Cloud Build buildType v1.
מגבלות
- Cloud Build יוצר אישור המקור של Build רק לארטיפקטים שמאוחסנים ב-Artifact Registry.
- קבצים מצורפים במאגר, כולל אישור המקור של Build, לא כפופים למדיניות ניקוי. במקום זאת, הקבצים המצורפים נמחקים כשהתמונה שאליה הם מצורפים נמחקת. מידע נוסף זמין במאמר ניהול קבצים מצורפים באמצעות מדיניות ניקוי.
לפני שמתחילים
-
מפעילים את ממשקי ה-API של Cloud Build, Container Analysis ו-Artifact Registry.
תפקידים שנדרשים להפעלת ממשקי API
כדי להפעיל ממשקי API, נדרשת ההרשאה
serviceusage.services.enable. אם יצרתם את הפרויקט, סביר להניח שכבר יש לכם את ההרשאה הזו דרך התפקיד 'בעלים' (roles/owner). אחרת, תוכלו לקבל את ההרשאה הזו דרך התפקיד 'אדמין בממשק 'שימוש בשירות'' (roles/serviceusage.serviceUsageAdmin). איך מקצים תפקידים כדי להשתמש בדוגמאות של שורת הפקודה במדריך הזה, צריך להתקין ולהגדיר את Google Cloud SDK.
ודאו שיש לכם את קוד המקור.
יש לכם מאגר ב-Artifact Registry.
יצירת אישור המקור של Build
בהוראות הבאות מוסבר איך ליצור אישור המקור של Build עבור קובצי אימג' של קונטיינר שמאוחסנים ב-Artifact Registry:
בקובץ תצורת ה-build, מוסיפים את השדה
imagesכדי להגדיר את Cloud Build לאחסון קובצי האימג' שנוצרו ב-Artifact Registry אחרי שה-build מסתיים.Cloud Build לא יכול ליצור נתוני מקור אם אתם מעבירים בדחיפה את קובץ האימג' ל-Artifact Registry באמצעות שלב
docker pushמפורש.בקטע הקוד הבא מוצגת הגדרת build ליצירת קובץ אימג' של קונטיינר ולאחסון שלו במאגר Docker ב-Artifact Registry:
YAML
steps: - name: 'gcr.io/cloud-builders/docker' args: [ 'build', '-t', 'LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE', '.' ] images: ['LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE']כאשר:
-
LOCATION: המיקום האזורי או הרב-אזורי של המאגר. -
PROJECT_ID: מזהה הפרויקט ב- Google Cloud . -
REPOSITORY: השם של מאגר Artifact Registry. -
IMAGE: השם של קובץ האימג' בקונטיינר.
JSON
{ "steps": [ { "name": "gcr.io/cloud-builders/docker", "args": [ "build", "-t", "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE", "." ] } ], "images": [ "LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE" ] }כאשר:
-
LOCATION: המיקום האזורי או הרב-אזורי של המאגר. -
PROJECT_ID: מזהה הפרויקט ב- Google Cloud . -
REPOSITORY: השם של מאגר Artifact Registry. -
IMAGE: השם של קובץ האימג' בקונטיינר.
-
בקטע
optionsשל קובץ ההגדרה של ה-build, מוסיפים את האפשרותrequestedVerifyOptionומגדירים את הערךVERIFIED.ההגדרה הזו מאפשרת יצירת שושלת ומגדירה את Cloud Build כך שיאמת שמטא-נתונים של שושלת קיימים. גרסאות Build יסומנו כהצלחה רק אם ייווצר תיעוד מקור.
YAML
options: requestedVerifyOption: VERIFIEDJSON
{ "options": { "requestedVerifyOption": "VERIFIED" } }מתחילים את הבנייה.
הצגת אישור המקור של Build
בקטע הזה מוסבר איך לצפות במטא-נתונים של אישור המקור של Build שנוצרו על ידי Cloud Build. אפשר לאחזר את המידע הזה למטרות ביקורת.
אפשר לגשת למטא-נתונים של אישור המקור של Build של קונטיינרים באמצעות חלונית הצד תובנות אבטחה במסוף Google Cloud או באמצעות ה-CLI של gcloud.
console
בחלונית הצדדית תובנות אבטחה מוצגת סקירה כללית של פרטי האבטחה של ארטיפקטים שמאוחסנים ב-Artifact Registry.
כדי לראות את החלונית Security insights:
פותחים את הדף Build History במסוף Google Cloud :
בטבלה עם הגרסאות, מאתרים את השורה עם הגרסה שרוצים לראות לגביה תובנות בנושא אבטחה.
בעמודה תובנות בנושא אבטחה, לוחצים על הצגה.
כאן מוצגת החלונית תובנות בנושא אבטחה עבור הארטיפקט שנבחר.
בכרטיס Build מוצגים פרטי מקור וקישור. כדי לראות את קטע המידע על מקורות, לוחצים על סמל הקישור.
מידע נוסף על חלונית הצד ועל האופן שבו אפשר להשתמש ב-Cloud Build כדי להגן על שרשרת האספקה של התוכנה זמין במאמר הצגת תובנות לגבי אבטחת ה-build.
CLI של gcloud
כדי להציג את מטא-נתוני המקור של קובצי אימג' של קונטיינרים, מריצים את הפקודה הבאה:
gcloud artifacts docker images describe \
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH \
--show-provenance --format=FORMAT
מחליפים את מה שכתוב בשדות הבאים:
-
LOCATION: המיקום האזורי או הרב-אזורי של המאגר. -
PROJECT_ID: מזהה הפרויקט ב- Google Cloud . -
REPOSITORY: השם של מאגר Artifact Registry. -
IMAGE: השם של קובץ האימג' בקונטיינר. -
HASH: ערך הגיבוב (hash) מסוג sha256 של התמונה. אפשר למצוא את זה בפלט של הבנייה. -
FORMAT: הגדרה אופציונלית שבה אפשר לציין פורמט פלט.
פלט לדוגמה
מקורות המידע על הבנייה נראים כך:
image_summary:
digest: sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
fully_qualified_digest: us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
registry: us-central1-docker.pkg.dev
repository: my-repo
slsa_build_level: 0
provenance_summary:
provenance:
- build:
inTotoSlsaProvenanceV1:
_type: https://in-toto.io/Statement/v1
predicate:
buildDefinition:
buildType: https://cloud.google.com/build/gcb-buildtypes/google-worker/v1
externalParameters:
buildConfigSource:
path: cloudbuild.yaml
ref: refs/heads/main
repository: git+https://github.com/my-username/my-git-repo
substitutions: {}
internalParameters:
systemSubstitutions:
BRANCH_NAME: main
BUILD_ID: e73ca1d4-ec4a-4ea6-acdd-ac8bb16dcc79
COMMIT_SHA: 525c52c501739e6df0609ed1f944c1bfd83224e7
LOCATION: us-west1
PROJECT_NUMBER: '265426041527'
REF_NAME: main
REPO_FULL_NAME: my-username/my-git-repo
REPO_NAME: my-git-repo
REVISION_ID: 525c52c501739e6df0609ed1f944c1bfd83224e7
SHORT_SHA: 525c52c
TRIGGER_BUILD_CONFIG_PATH: cloudbuild.yaml
TRIGGER_NAME: github-trigger-staging
triggerUri: projects/265426041527/locations/us-west1/triggers/a0d239a4-635e-4bd3-982b-d8b72d0b4bab
resolvedDependencies:
- digest:
gitCommit: 525c52c501739e6df0609ed1f944c1bfd83224e7
uri: git+https://github.com/my-username/my-git-repo@refs/heads/main
- digest:
sha256: 154fcd4d2d65c6a35b06b98053a0829c581e223d530be5719326f5d85d680e8d
uri: gcr.io/cloud-builders/docker@sha256:154fcd4d2d65c6a35b06b98053a0829c581e223d530be5719326f5d85d680e8d
runDetails:
builder:
id: https://cloudbuild.googleapis.com/GoogleHostedWorker
byproducts:
- {}
metadata:
finishedOn: '2023-08-01T19:57:10.734471Z'
invocationId: https://cloudbuild.googleapis.com/v1/projects/my-project/locations/us-west1/builds/e73ca1d4-ec4a-4ea6-acdd-ac8bb16dcc79
startedOn: '2023-08-01T19:56:57.451553160Z'
predicateType: https://slsa.dev/provenance/v1
subject:
- digest:
sha256: 7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
name: https://us-central1-docker.pkg.dev/my-project/my-repo/my-image
- digest:
sha256: 7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
name: https://us-central1-docker.pkg.dev/my-project/my-repo/my-image:latest
createTime: '2023-08-01T19:57:14.810489Z'
envelope:
payload:
eyJfdHlwZSI6Imh0dHBzOi8vaW4tdG90by5pby9TdGF0ZW1lbnQvdMWQ0LWVjNGEtNGVhNi1hY2RkLWFjOGJiMTZkY2M3OSIsICJzdGFydGVkT24iOiIyMDIzLTA4LTAxVDE5OjU2OjU3LjQ1MTU1MzE2MFoiLCAiZmluaXNoZWRPbiI6IjIwMjMtMDgtMDFUMTk6NTc6MTAuNzM0NDcxWiJ9LCAiYnlwcm9kdWN0cyI6W3t9XX19fQ==...
payloadType: application/vnd.in-toto+json
signatures:
- keyid: projects/verified-builder/locations/global/keyRings/attestor/cryptoKeys/google-hosted-worker/cryptoKeyVersions/1
sig: MEUCIQCss8UlQL2feFePRJuKTE8VA73f85iqj4OJ9SvVPqTNwAIgYyuyuIrl1PxQC5B109thO24Y6NA4bTa0PJY34EHRSVE=
kind: BUILD
name: projects/my-project/occurrences/71787589-c6a6-4d6a-a030-9fd041e40468
noteName: projects/argo-qa/notes/intoto_slsa_v1_e73ca1d4-ec4a-4ea6-acdd-ac8bb16dcc79
resourceUri: https://us-central1-docker.pkg.dev/my-project/my-repo/my-image@sha256:7e9b6e7ba2842c91cf49f3e214d04a7a496f8214356f41d81a6e6dcad11f11e3
updateTime: '2023-08-01T19:57:14.810489Z'
כמה דברים חשובים שכדאי לשים לב אליהם בדוגמה הזו:
מקור: ה-build הופעל ממאגר ב-GitHub.
הפניה לאובייקט: השדות בשמות
digestו-fileHashמתייחסים לאותו אובייקט. השדהdigestשכלול בפלט לדוגמה מקודד בבסיס 16 (קידוד הקסדצימלי). אם אתם משתמשים בנתוני מקוריות בגרסה 0.1 של SLSA, הפלט שלכם משתמש בשדהfileHashשמקודד ב-base 64.חתימות: אם אתם משתמשים בנתוני מקור של SLSA בגרסה 0.1, הפלט שלכם מכיל שתי חתימות בשדה
envelope. החתימה הראשונה, עם שם המפתחprovenanceSigner, משתמשת בחתימה שתואמת ל-DSSE (בפורמט של קידוד לפני אימות (PAE)), שאפשר לאמת במדיניות של Binary Authorization. מומלץ להשתמש בחתימה הזו בשימושים חדשים של המקור הזה. החתימה השנייה, עם שם המפתחbuiltByGCB, מסופקת לשימוש במערכות מדור קודם.חשבונות שירות: החתימות שנכללות באופן אוטומטי בתיעוד המקור של Cloud Build עוזרות לכם לאמת את שירות ה-build שהפעיל את ה-build. אפשר גם להגדיר את Cloud Build כך שיתעד מטא-נתונים שניתנים לאימות לגבי חשבון השירות ששימש להפעלת build. מידע נוסף זמין במאמר בנושא חתימה על תמונות של קונטיינרים באמצעות Cosign.
Payload: דוגמת המידע על מקורות שמוצגת בדף הזה מקוצרת כדי שיהיה קל לקרוא אותה. הפלט בפועל יהיה ארוך יותר, כי המטען הייעודי (payload) הוא גרסה בקידוד Base64 של כל מטא-נתוני המקור.
יחסי תלות: יחסי התלות שאתם מציינים בקובץ הבנייה נכללים בתיעוד המקור, בשדה
resolvedDependencies.
הצגת מקורות של פריטי מידע שאינם קשורים למאגרי תגים
כשמעלים ארטיפקטים של build ל-Artifact Registry, Cloud Build יוצר מטא-נתונים של מקוריות SLSA לאפליקציות עצמאיות של Go, Java (Maven), Python ו-Node.js (npm).
כדי ליצור את מטא-נתוני המקור של הארטיפקטים, מריצים build באמצעות Cloud Build. אפשר להשתמש באחד מהמדריכים הבאים:
- פיתוח אפליקציות Go עצמאיות
- פיתוח אפליקציות Java עצמאיות
- פיתוח אפליקציות עצמאיות ב-Python
- איך בונים אפליקציות עצמאיות ב-Node.js
בסיום הבנייה, רושמים את
BuildID.אפשר לאחזר את מטא-נתוני המקור באמצעות קריאה ישירה ל-API או באמצעות
gcloudCLI. כדי למצוא את המקור של גרסת build ספציפית, צריך לסנן את התוצאות לפי מזהה ה-build.gcloud
gcloud container analysis occurrences list \ --project="PROJECT_ID" \ --filter='kind="BUILD" AND build.inTotoSlsaProvenanceV1.predicate.runDetails.metadata.invocationId="https://cloudbuild.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/builds/BUILD_ID"' \ --format=jsoncurl
alias gcurl='curl -H "Authorization: Bearer $(gcloud auth print-access-token)" -H "Content-Type: application/json"' PROJECT_ID="PROJECT_ID" LOCATION="LOCATION" BUILD_ID="BUILD_ID" FILTER="kind%3D%22BUILD%22%20AND%20build.inTotoSlsaProvenanceV1.predicate.runDetails.metadata.invocationId%3D%22https%3A%2F%2Fcloudbuild.googleapis.com%2Fv1%2Fprojects%2F${PROJECT_ID}%2Flocations%2F${LOCATION}%2Fbuilds%2F${BUILD_ID}%22" gcurl "https://containeranalysis.googleapis.com/v1/projects/${PROJECT_ID}/occurrences?filter=${FILTER}"מחליפים את הפלייסהולדרים בדוגמאות הקודמות:
-
PROJECT_ID: מזהה הפרויקט ב- Google Cloud . -
LOCATION: האזור שבו בוצעה הבנייה, למשלus-central1. -
BUILD_ID: המזהה של הגרסה שמעניינת אתכם.
הפונקציה מחזירה את המופעים הספציפיים של סוג
BUILDשתואמים למזהה הבנייה שצוין.הערה: סינון של שדות JSON מוטמעים כמו
invocationIdעשוי להיות איטי יותר מסינון של שדות באינדקס ברמה העליונה, במיוחד בפרויקטים עם מספר גדול מאוד של מקרים.-
אימות המקור
בקטע הזה מוסבר איך לאמת את מקורות ה-build של קובצי אימג' בקונטיינר.
אימות המקור של הבנייה עוזר לכם:
- לוודא שפריטי ה-build נוצרים ממקורות ומתהליכי build מהימנים
- לוודא שהמטא-נתונים של שרשרת האספקה שמתארים את תהליך build מלאים ואותנטיים
מידע נוסף זמין במאמר בנושא הגנה על גרסאות build.
אימות מקור באמצעות הכלי לאימות SLSA
כלי האימות של SLSA הוא כלי CLI בקוד פתוח שמאפשר לאמת את תקינות הבנייה על סמך מפרטי SLSA.
אם הכלי לאימות מוצא בעיות, הוא מחזיר הודעות שגיאה מפורטות שיעזרו לכם לעדכן את תהליך build ולצמצם את הסיכונים.
כדי להשתמש בכלי לאימות SLSA:
מתקינים גרסה 2.1 ואילך ממאגר slsa-verifier
go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@VERSIONב-CLI, מגדירים משתנה למזהה התמונה:
export IMAGE=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASHכאשר:
-
LOCATION: מיקום אזורי או רב-אזורי. -
PROJECT_ID: Google Cloud מזהה הפרויקט. -
REPOSITORY: שם המאגר. -
IMAGE: שם התמונה. -
HASH: ערך הגיבוב (hash) מסוג sha256 של התמונה. אפשר למצוא את זה בפלט של הבנייה.
-
נותנים ל-CLI של gcloud הרשאות גישה לנתוני המקור כדי שמאמת ה-SLSA יוכל לגשת אליהם:
gcloud auth configure-docker LOCATION-docker.pkg.devמאחזרים את מקור התמונה ושומרים אותו כ-
JSON:gcloud artifacts docker images describe $IMAGE --format json --show-provenance > provenance.jsonאימות המקור:
slsa-verifier verify-image "$IMAGE" \ --provenance-path provenance.json \ --source-uri SOURCE \ --builder-id=BUILDER_IDכאשר:
-
SOURCEהוא מזהה המשאבים האחיד (URI) של מאגר המקור של התמונה, לדוגמהgithub.com/my-repo/my-application. BUILDER_IDהמזהה הייחודי של הכלי ליצירת תוספים, לדוגמהhttps://cloudbuild.googleapis.com/GoogleHostedWorker
אם רוצים להדפיס את המקור המאומת לשימוש במנוע מדיניות, משתמשים בפקודה הקודמת עם הדגל
--print-provenance.הפלט אמור להיראות כך:
PASSED: Verified SLSA provenanceאוFAILED: SLSA verification failed: <error details>.-
מידע נוסף על דגלים אופציונליים זמין במאמר בנושא אפשרויות.
אימות מטא-נתוני המקור באמצעות ה-CLI של gcloud
כדי לוודא שלא נעשה שינוי באישור המקור של Build, אפשר לאמת את המקור באמצעות השלבים הבאים:
יוצרים ספרייה חדשה ועוברים אליה.
mkdir provenance && cd provenanceבעזרת המידע מהשדה
keyid, מאתרים את המפתח הציבורי.gcloud kms keys versions get-public-key 1 --location global --keyring attestor \ --key builtByGCB --project verified-builder --output-file my-key.pubהמאפיין
payloadמכיל את ייצוג ה-JSON של מקור הנתונים, בקידוד base64url. מפענחים את הנתונים ומאחסנים אותם בקובץ.gcloud artifacts docker images describe \ LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \ --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v0.1") | .envelope.payload' | tr '\-_' '+/' | base64 -d > provenance.jsonכשסוגי המקורות של SLSA גרסה 0.1 וגרסה 1.0 זמינים, הם מאוחסנים. אם רוצים לסנן לפי גרסה 1.0, צריך לשנות את
predicateTypeל-https://slsa.dev/provenance/v1. לדוגמה:gcloud artifacts docker images describe \ LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \ --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v1") | .envelope.payload' | tr '\-_' '+/' | base64 -d > provenance.jsonהמעטפה מכילה גם את החתימה על המקור. מפענחים את הנתונים ומאחסנים אותם בקובץ.
gcloud artifacts docker images describe LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \ --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v0.1") | .envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.binאם רוצים לסנן לפי גרסה 1.0, צריך לשנות את
predicateTypeל-https://slsa.dev/provenance/v1. לדוגמה:gcloud artifacts docker images describe LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \ --format=json | jq -r '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v1") | .envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.binהפקודה שלמעלה מתייחסת לחתימת המקור הראשונה (
.provenance_summary.provenance[0].envelope.signatures[0]) שנחתמה על ידי המפתחprovenanceSigner. המטען הייעודי חתום על המעטפה בפורמט PAE. כדי לאמת את המקור, מריצים את הפקודה הזו כדי להמיר את המקור לפורמט PAE הצפוי של"DSSEv1" + SP + LEN(type) + SP + type + SP + LEN(body) + SP + body.echo -n "DSSEv1 28 application/vnd.in-toto+json $(cat provenance.json | wc -c) $(cat provenance.json)" > provenance.jsonמאמתים את החתימה.
openssl dgst -sha256 -verify my-key.pub -signature signature.bin provenance.jsonאחרי אימות מוצלח, הפלט הוא
Verified OK.
המאמרים הבאים
- הגדרת Cloud Build למעקב אחרי מי שיזם את ה-build
- שימוש בסריקת פגיעויות בצינור עיבוד הנתונים של Cloud Build
- מידע נוסף על אבטחת שרשרת האספקה של תוכנות