本页介绍了如何生成 build 来源、查看输出并对其进行验证。
构建来源是关于 build 的可验证数据的集合。来源元数据包括已构建映像的摘要、输入源位置、构建参数和构建时长等详细信息。您可以使用这些信息来确保您使用的构建工件准确可靠,并且由可信的来源和构建器创建。
Cloud Build 支持根据 SLSA 版本 0.1 和 1.0 的规范生成符合软件工件的供应链级别 (SLSA) 3 级保证的 build 出处。
作为对 SLSA v1.0 规范的支持,Cloud Build 会在 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。
准备好源代码。
生成 build 出处
以下说明介绍了如何为存储在 Artifact Registry 中的容器映像生成构建源代码:
在构建配置文件中,添加
images
字段以配置 Cloud Build 在构建完成后将构建的映像存储在 Artifact Registry 中。如果您使用显式
docker push
步骤将映像推送到 Artifact Registry,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
:容器映像的名称。
在 build 配置的
options
部分中,添加requestedVerifyOption
选项并将其值设置为VERIFIED
。此设置会启用来源生成,并配置 Cloud Build 以验证是否存在来源元数据。只有在生成了来源时,构建才会被标记为成功。
YAML
options: requestedVerifyOption: VERIFIED
JSON
{ "options": { "requestedVerifyOption": "VERIFIED" } }
开始构建。
查看构建来源
本部分介绍如何查看 Cloud Build 创建的构建来源元数据。您可以获取此信息以进行审核。
您可以使用 Google Cloud 控制台内的安全分析侧边栏或 gcloud CLI 访问容器的 build 来源元数据。
控制台
安全性数据分析侧边栏提供了存储在 Artifact Registry 中的工件的安全信息的简要概览。
如需查看安全数据洞见面板,请执行以下操作:
打开 Google Cloud 控制台中的构建记录页面:
选择您的项目,然后点击打开。
在区域下拉菜单中,选择您运行 build 时所在的区域。
在包含 build 的表格中,找到您要查看安全数据洞见的 build 所在的行。
在安全性数据分析列下,点击查看。
系统随即会显示所选工件的安全数据洞见面板。
Build 卡片会显示来源详情和链接。您可以点击链接图标查看来源代码段。
如需详细了解边栏以及如何使用 Cloud Build 帮助保护软件供应链,请参阅查看 build 安全数据分析。
gcloud CLI
如需查看容器映像的来源元数据,请运行以下命令:
gcloud artifacts docker images describe \
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH \
--show-provenance --format=FORMAT
替换以下内容:
输出示例
build 来源类似于以下内容:
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
字段采用基数 16(十六进制)编码。如果您使用的是 SLSA 版本 0.1 的来源,则输出将使用以 base 64 编码的fileHash
字段。签名:如果您使用的是 SLSA 版本 0.1 的来源,则输出中的
envelope
字段包含两个签名。第一个签名(键名称为provenanceSigner
)使用符合 DSSE 标准的签名(采用预身份验证编码 (PAE) 格式),可在二进制授权政策中进行验证。我们建议您在对此来源进行新用途时使用此签名。第二个签名(密钥名称为builtByGCB
)供旧版使用。服务账号:Cloud Build 历史记录中自动包含的签名可帮助您验证执行了构建的构建服务。您还可以配置 Cloud Build 来记录有关用于启动 build 的服务账号的可验证元数据。如需了解详情,请参阅使用 cosign 对容器映像进行签名。
载荷:为方便阅读,本页上显示的来源示例已缩减。实际输出将更长,因为载荷是所有来源元数据的 base-64 编码版本。
查看非容器工件的来源
当您将 build 工件上传到 Artifact Registry 时,Cloud Build 会为独立的 Go、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
搜索,以查找与 build 工件关联的来源信息。
验证出处
本部分介绍了如何验证容器映像的构建来源。
验证 build 来源有助于您:
- 确认构建工件是从可信来源和构建器生成的
- 确保描述构建流程的源代码元数据完整且真实
如需了解详情,请参阅保护 build。
使用 SLSA 验证器验证来源
SLSA 验证器是一种开源 CLI 工具,用于根据 SLSA 规范验证 build 完整性。
如果验证程序发现问题,它会返回详细的错误消息,以帮助您更新构建流程并降低风险。
如需使用 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 哈希值。您可以在构建的输出中找到此值。
向 gcloud CLI 授权,以便 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
构建器的唯一 ID,例如https://cloudbuild.googleapis.com/GoogleHostedWorker
如果您想输出经过验证的来源以在政策引擎中使用,请将上一条命令与
--print-provenance
标志搭配使用。输出类似于以下内容:
PASSED: Verified SLSA provenance
或FAILED: SLSA verification failed: <error details>
。
如需详细了解可选标志,请参阅选项。
使用 gcloud CLI 验证来源元数据
如果您要验证 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 | '.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
上述命令引用了第一个由
provenanceSigner
密钥签名的来源签名 (.provenance_summary.provenance[0].envelope.signatures[0]
)。载荷在 PAE 格式信封上签名。为了验证这一点,请运行以下命令,将来源转换为预期的"DSSEv1" + SP + LEN(type) + SP + type + SP + LEN(body) + SP + body
PAE 格式。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
。