このページでは、ビルドの来歴を生成し、出力を表示して検証する方法について説明します。
ビルドの来歴は、ビルドに関する検証可能なデータの集まりです。 来歴のメタデータには、ビルドされたイメージのダイジェスト、入力ソースの場所、ビルド引数、ビルド時間などの詳細情報が含まれます。この情報を使用して、使用しているビルド アーティファクトが正確で信頼性が高く、信頼できるソースとビルダーによって作成されていることを確認できます。
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 の出所のみを提供します。
- ビルドの出所などの Docker リポジトリのアタッチメントは、クリーンアップ ポリシーの対象ではありません。代わりに、添付ファイルは、添付先の画像が削除されると削除されます。詳細については、クリーンアップ ポリシーを使用してアタッチメントを管理するをご覧ください。
始める前に
- 
  
   
   
     
   
  
   
   
     
   
  
 
  
  
    
      Enable the Cloud Build, Container Analysis, and Artifact Registry APIs. Roles required to enable APIs To enable APIs, you need the Service Usage Admin IAM role ( roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles.
- このガイドのコマンドラインの例を使用するには、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 プロジェクト ID。
- 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 プロジェクト ID。
- REPOSITORY: 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 のプロベナンスを使用している場合、出力では base 64 でエンコードされた- fileHashフィールドが使用されます。
- 署名: SLSA バージョン 0.1 のプロベナンスを使用している場合、出力の - envelopeフィールドには 2 つの署名が含まれます。鍵名が- provenanceSignerの最初の署名は、Binary Authorization ポリシーで検証可能な DSSE 準拠の署名(事前認証のエンコード(PAE)形式)を使用します。この来歴の新しい用途では、この署名を使用することをおすすめします。以前の用途には、鍵名が- builtByGCBの別の署名が使用されます。
- サービス アカウント: Cloud Build の来歴に自動的に含まれる署名は、ビルドを実行したビルド サービスの検証に役立ちます。ビルドの開始に使用されたサービス アカウントに関する検証可能なメタデータを記録するように Cloud Build を構成することもできます。詳細については、cosign を使用してコンテナ イメージに署名するをご覧ください。 
- ペイロード: このページに表示されている来歴の例は、読みやすくするために短縮されています。ペイロードはすべての来歴メタデータの base-64 エンコード バージョンであるため、実際の出力は長くなります。 
- 依存関係: ビルドファイルで指定した依存関係は、 - resolvedDependenciesフィールドの来歴に含まれます。
コンテナ以外のアーティファクトのプロベナンスを表示する
Cloud Build は、ビルド アーティファクトを Artifact Registry にアップロードする際に、スタンドアロン Go、Java(Maven)、Python、Node.js(npm)アプリケーションの SLSA 来歴メタデータを生成します。来歴のメタデータは、直接 API 呼び出しを行うことで取得できます。
- アーティファクトの来歴メタデータを生成するには、Cloud Build でビルドを実行します。次のいずれかのガイドを使用します。 - スタンドアロンの Go アプリケーションをビルドする
- スタンドアロンの Java アプリケーションをビルドする
- スタンドアロンの Python アプリケーションをビルドする
- スタンドアロン Node.js アプリケーションをビルドする
 - ビルドが完了したら、 - 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 で、イメージ識別子の変数を設定します。 - export IMAGE=LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH- ここで - LOCATION: リージョンまたはマルチリージョンのロケーション。
- PROJECT_ID: Google Cloud プロジェクト ID
- REPOSITORY: リポジトリの名前。
- 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 | 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 でフィルタする場合は、 - 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 パイプラインで脆弱性スキャンを使用する
- ソフトウェア サプライ チェーンのセキュリティについて学習する