このページでは、ビルドの来歴を生成し、出力を表示して検証する方法について説明します。
ビルドの来歴は、ビルドに関する検証可能なデータの集まりです。 来歴のメタデータには、ビルドされたイメージのダイジェスト、入力ソースの場所、ビルド引数、ビルド時間などの詳細情報が含まれます。この情報を使用して、使用しているビルド アーティファクトが信頼できるソースとビルダーによって作成された正確で信頼できるものであることを確認できます。
Cloud Build は、SLSA バージョン 0.1 と 1.0 の仕様に基づく、ソフトウェア アーティファクトのサプライ チェーン レベル(SLSA)レベル 3 の保証を満たすビルドの来歴の生成をサポートしています。
SLSA v1.0 仕様のサポートの一部として、Cloud Build はビルドの来歴で buildType
の詳細を提供します。buildType
スキーマを使用すると、ビルドプロセスに使用されるパラメータ化されたテンプレートを把握できます。これには、Cloud Build が記録する値と、それらの値のソースが含まれます。詳細については、Cloud Build buildType v1 をご覧ください。
制限事項
- Cloud Build は、Artifact Registry に保存されているアーティファクトのビルドの来歴のみを生成します。
- SLSA v1.0 と v0.1 の両方の来歴を取得するには、トリガーを使用してビルドする必要があります。gcloud CLI を使用してビルドを手動で開始した場合、Cloud Build は SLSA v0.1 の来歴のみを提供します。
始める前に
-
Enable the Cloud Build, Container Analysis, and Artifact Registry APIs.
このガイドのコマンドラインの例を使用するには、Google Cloud SDK をインストールして構成します。
ソースコードを用意します。
Artifact Registry にリポジトリを用意します。
ビルドの来歴を生成する
次の手順では、Artifact Registry に保存するコンテナ イメージのビルドの来歴を生成する方法について説明します。
ビルド構成ファイルに
images
フィールドを追加して、ビルドが完了した後にビルドされたイメージを Artifact Registry に保存するように Cloud Build を構成します。明示的な
docker push
ステップを使用して Artifact Registry にイメージを push する場合、Cloud Build は来歴を生成できません。次のスニペットは、コンテナ イメージをビルドして Artifact Registry の Docker リポジトリにイメージを保存するビルド構成を示しています。
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 プロジェクト IDREPOSITORY
: 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 プロジェクト IDREPOSITORY
: Artifact Registry リポジトリの名前。IMAGE
: コンテナ イメージの名前。
ビルド構成の
options
セクションで、requestedVerifyOption
オプションを追加し、値をVERIFIED
に設定します。この設定により、来歴の生成が有効になり、来歴メタデータが存在することを確認するように Cloud Build が構成されます。ビルドが成功としてマークされるのは、来歴が生成された場合のみです。
YAML
options: requestedVerifyOption: VERIFIED
JSON
{ "options": { "requestedVerifyOption": "VERIFIED" } }
ビルドを開始します。
ビルドの来歴を表示する
このセクションでは、Cloud Build によって作成されたビルドの来歴メタデータを表示する方法について説明します。この情報は後で監査目的で取得できます。
コンテナのビルドの来歴のメタデータには、Google Cloud コンソールの [セキュリティ分析] サイドパネルを使用するか、gcloud CLI を使用してアクセスできます。
Console
[セキュリティ分析情報] サイドパネルには、Artifact Registry に保存されているアーティファクトのセキュリティ情報の概要が表示されます。
[セキュリティ分析情報] パネルを表示するには:
Google Cloud コンソールで [ビルド履歴] ページを開きます。
プロジェクトを選択し、[開く] をクリックします。
[リージョン] プルダウン メニューで、ビルドを実行したリージョンを選択します。
ビルドの表で、セキュリティ分析情報を表示するビルドを含む行を見つけます。
[セキュリティ分析情報] 列で [表示] をクリックします。
選択したアーティファクトの [セキュリティ分析情報] パネルが表示されます。
[ビルド] カードには、来歴の詳細とリンクが表示されます。リンクアイコンをクリックすると、来歴スニペットを表示できます。
サイドパネルと、Cloud Build を使用してソフトウェア サプライ チェーンを保護する方法の詳細については、ビルドのセキュリティ分析情報を表示するをご覧ください。
gcloud CLI
コンテナ イメージの来歴メタデータを表示するには、次のコマンドを実行します。
gcloud artifacts docker images describe \
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH \
--show-provenance --format=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'
この例で注意すべき重要な点がいくつかあります。
オブジェクト参照:
digest
という名前のフィールドとfileHash
という名前のフィールドは同じオブジェクトを参照しています。サンプル出力に含まれるdigest
フィールドは、base16(16 進数)でエンコードされています。SLSA バージョン 0.1 の来歴を使用している場合、出力では base64 でエンコードされたfileHash
フィールドが使用されます。署名: SLSA バージョン 0.1 の来歴を使用している場合、出力には
envelope
フィールドに 2 つの署名が含まれます。鍵名がprovenanceSigner
の最初の署名は、Binary Authorization ポリシーで検証可能な DSSE 準拠の署名(事前認証のエンコード(PAE)形式)を使用します。この来歴の新しい用途では、この署名を使用することをおすすめします。以前の用途には、鍵名がbuiltByGCB
の別の署名が使用されます。サービス アカウント: Cloud Build の来歴に自動的に含まれる署名は、ビルドを実行したビルド サービスの検証に役立ちます。ビルドの開始に使用されたサービス アカウントに関する検証可能なメタデータを記録するように Cloud Build を構成することもできます。詳細については、cosign を使用してコンテナ イメージに署名するをご覧ください。
ペイロード: このページに表示されている来歴の例は、読みやすくするために短縮されています。ペイロードはすべての来歴メタデータの base-64 エンコード バージョンであるため、実際の出力は長くなります。
コンテナ以外のアーティファクトの来歴を表示する
Cloud Build は、ビルド アーティファクトを Artifact Registry にアップロードする際に、スタンドアロン Java(Maven)、Python、Node.js(npm)アプリケーションの SLSA 来歴メタデータを生成します。来歴のメタデータは、直接 API 呼び出しを行うことで取得できます。
アーティファクトの来歴メタデータを生成するには、Cloud Build でビルドを実行します。次のいずれかのガイドを使用します。
ビルドが完了したら、
BuildID
をメモします。ターミナルで次の API 呼び出しを実行して、来歴メタデータを取得します。ここで、PROJECT_ID は Google Cloud プロジェクトに関連付けられた ID です。
alias gcurl='curl -H"Authorization: Bearer $(gcloud auth print-access-token)"' gcurl 'https://containeranalysis.googleapis.com/v1/projects/PROJECT_ID/occurrences'
このタイプのアーティファクトの来歴メタデータにアクセスするには、API 呼び出しを使用する必要があります。コンテナ以外のアーティファクトの来歴メタデータは、Google Cloud コンソールに表示されず、gcloud CLI からアクセスすることもできません。
プロジェクトの発生で
BuildID
で検索して、ビルド アーティファクトに関連付けられた来歴情報を探します。
来歴を検証する
このセクションでは、コンテナ イメージのビルドの来歴を検証する方法について説明します。
ビルドの来歴を検証すると、次のことができます。
- 信頼できるソースとビルダーからビルド アーティファクトが生成されていることを確認する
- ビルドプロセスを記述する来歴メタデータが完全で、真正であることを確認する
詳細については、ビルドを保護するをご覧ください。
SLSA 検証ツールを使用して来歴を検証する
SLSA 検証ツールは、SLSA 仕様に基づいてビルドの完全性を検証するためのオープンソースの CLI ツールです。
検証ツールは問題を検出すると、ビルドプロセスの更新とリスクの軽減に役立つ詳細なエラー メッセージを返します。
SLSA 検証ツールを使用するには:
slsa-verifier リポジトリからバージョン 2.1 以降をインストールします。
go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@VERSION
CLI で、イメージ ID の変数を設定します。
export IMAGE=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH
コマンドのプレースホルダ値を、次のように置き換えます。
LOCATION
: リージョンまたはマルチリージョンのロケーション。PROJECT_ID
: Google Cloud プロジェクト IDREPOSITORY
: リポジトリの名前。IMAGE
: イメージ名HASH
: イメージの sha256 ハッシュ値。これはビルドの出力で確認できます。
SLSA 検証ツールが来歴データにアクセスできるように gcloud CLI を承認します。
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
ビルダーの一意の ID(例:https://cloudbuild.googleapis.com/GoogleHostedWorker
)
ポリシー エンジンで使用するために検証済みの来歴を出力する場合は、
--print-provenance
フラグを指定して前のコマンドを使用します。出力は次のようになります。
PASSED: Verified SLSA provenance
またはFAILED: SLSA verification failed: <error details>
。
オプション フラグの詳細については、オプションをご覧ください。
gcloud CLI で来歴メタデータを検証する
ビルドの来歴メタデータが改ざんされていないことを確認するには、次の手順を行うことで来歴を検証できます。
新しいディレクトリを作成し、そのディレクトリに移動します。
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
には、base64url でエンコードされた来歴の 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.payload' | tr '\-_' '+/' | base64 -d > provenance.json
SLSA バージョン 0.1 と 1.0 の両方の来歴タイプは、使用可能な場合は保存されます。バージョン 1.0 でフィルタする場合は、
https://slsa.dev/provenance/v1
を使用するようにpredicateType
を変更します。次に例を示します。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 | '.provenance_summary.provenance[] | select(.build.intotoStatement.predicateType == "https://slsa.dev/provenance/v0.1") | .envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.bin
バージョン 1.0 でフィルタする場合は、
https://slsa.dev/provenance/v1
を使用するようにpredicateType
を変更します。次に例を示します。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
上記のコマンドは、
provenanceSigner
鍵によって署名された最初の来歴署名(.provenance_summary.provenance[0].envelope.signatures[0]
)を参照します。ペイロードは 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 を構成する
- Cloud Build パイプラインで脆弱性スキャンを使用する
- ソフトウェア サプライ チェーンのセキュリティについて学習する