使用签名来源和 Binary Authorization

本页面介绍了如何使用 Cloud Build 查看构建来源元数据和控制部署。

构建来源是关于 Cloud Build 运行的构建的一组可验证数据。来源元数据包括已构建映像的摘要、输入源位置、构建参数和构建时长等详细信息。

为了帮助您保护软件供应链的安全,Cloud Build 会记录来源元数据并在构建时为容器映像创建证明。您可以使用来源元数据进行审核,并使用证明通过 Binary Authorization 控制部署。

限制

Cloud Build 在同一项目中生成所有 Binary Authorization 和 Container Analysis 资源。如果您在另一个项目中运行部署平台,则在配置 Binary Authorization 时,必须在添加 built-by-cloud-build 证明者时引用 Cloud Build 项目。

准备工作

  • 如需查看生成的关于构建来源的元数据:

    启用 Cloud Build, Container Analysis, and Artifact Registry API。

    启用 API

  • 如需使用 Binary Authorization 控制部署并查看证明者元数据:

    1. 启用 Cloud Build, Binary Authorization, and Artifact Registry API。

      启用 API

    2. 为您的平台设置 Binary Authorization

查看构建来源

本部分介绍如何查看 Cloud Build 创建的构建来源元数据。

使用 Cloud Build 构建映像时,系统会自动记录映像的构建来源。您可以在稍后获取此信息用于审核。要生成来源元数据,请使用 Cloud Build 运行构建

要查看来源元数据,请运行以下命令:

gcloud artifacts docker images describe \
LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH \
--show-provenance

将命令中的占位值替换为以下内容:

  • LOCATION:单区域或多区域位置
  • PROJECT_ID:Google Cloud 项目 ID。
  • REPOSITORY:代码库的名称。
  • IMAGE:映像的名称。
  • HASH:映像的 sha256 哈希值。您可以在构建的输出中找到此值。

输出是容器来源,如 SLSA 来源规范中所述。例如:

image_summary:
  digest: sha256:991ff3a4548c72e671070be2e86ff684fd0924f6b75ee60d25d85c8cdfde1293
  fully_qualified_digest: us-east1-docker.pkg.dev/PROJECT_ID/my-repo/my-image@sha256:991ff3a4548c72e671070be2e86ff684fd0924f6b75ee60d25d85c8cdfde1293
  registry: us-east1-docker.pkg.dev
  repository: my-repo
provenance_summary:
  provenance:
  - createTime: '2021-09-24T16:20:36.854156Z'
    dsseAttestation:
      envelope:
        payload: eyJfdHlwZS...
        payloadType: application/vnd.in-toto+json
        signatures:
        - keyid: projects/verified-builder/locations/global/keyRings/attestor/cryptoKeys/builtByGCB/cryptoKeyVersions/1
          sig: MEQCIHusA75t6LoyCngZ1_ACc-wWOlTThW6VKCyz75bnmSU0AiBYV50eFWQlDlp2cF-OV1u6j1_CtmrFdCNJCdyB6pYFsw==
      statement:
        predicateType: https://slsa.dev/provenance/v0.1
        provenance:
          builderConfig:
            id: https://cloudbuild.googleapis.com/Worker@v336731714
          metadata:
            buildFinishedOn: '2021-09-24T16:20:35.828284Z'
            buildInvocationId: c2f645df-f705-4aab-8d8f-ba2b1260f8ab
            buildStartedOn: '2021-09-24T16:20:23.224165401Z'
          recipe:
            arguments:
            - '@type': type.googleapis.com/google.devtools.cloudbuild.v1.BuildStep
              args:
              - build
              - --network
              - cloudbuild
              - --no-cache
              - -t
              - us-east1-docker.pkg.dev/PROJECT_ID/my-repo/my-image:tag1
              ....

如果您要验证元数据未被篡改,可以执行以下步骤来验证来源:

  1. 创建一个新目录,并转到该目录。

    mkdir provenance && cd provenance
    
  2. 使用 keyid 字段中的信息获取公钥。

    gcloud kms keys versions get-public-key 1 --location global --keyring attestor \
    --key builtByGCB --project verified-builder --output-file my-key.pub
    
  3. 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[0].dsseAttestation.envelope.payload' | tr '\-_' '+/' | base64 -d > provenance.json
    
  4. 信包还包含来源的签名。解码该数据并将其存储在一个文件中。

    gcloud artifacts docker images describe LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE@sha256:HASH --show-provenance \
    --format=json | jq -r '.provenance_summary.provenance[0].dsseAttestation.envelope.signatures[0].sig' | tr '\-_' '+/' | base64 -d > signature.bin
    
  5. 验证签名。

    openssl dgst -sha256 -verify my-key.pub -signature signature.bin provenance.json
    

    验证成功后,输出为 Verified OK

要求您的映像具有关联的来源元数据

如果 Cloud Build 未生成来源元数据,构建仍会成功完成。如需在 Cloud Build 没有为您的映像生成来源元数据时覆盖默认行为并且使构建失败,请将 requestedVerifyOption: VERIFIED 选项添加到 cloudbild.yaml 文件中:

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: [ 'build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/quickstart-docker-repo/quickstart-image:tag1', '.' ]
images:
- 'us-central1-docker.pkg.dev/$PROJECT_ID/quickstart-docker-repo/quickstart-image:tag1'
options:
  requestedVerifyOption: VERIFIED

添加 requestedVerifyOption 后,只有在 Cloud Build 可以生成相应的来源元数据时,Cloud Build 才会将构建标记为成功。这也会影响专用池中构建的映像,为这些映像生成来源元数据和证明。

使用 Binary Authorization 控制部署

Binary Authorization 中的政策是一组规则,用于管理映像的部署。您可以将规则配置为要求具有数字签名的证明

Cloud Build 会在构建时生成证明并进行签名。借助 Binary Authorization,您可以使用 built-by-cloud-build 证明者来验证证明,并仅部署 Cloud Build 构建的映像。首次在项目中运行构建时,系统会创建 built-by-cloud-build 证明者

如需仅允许部署 Cloud Build 构建的映像,请执行以下步骤:

控制台

  1. 转到 Google Cloud Console 中的 Binary Authorization 页面。

    转到 Binary Authorization

  2. 政策标签页中,点击修改政策

  3. 修改政策对话框中,选择只允许已被以下所有证明者批准的映像

  4. 点击添加证明者

  5. 添加证明者对话框中,执行以下操作:

    1. 选择根据项目和证明者名称添加并执行以下步骤:
      1. 项目名称字段中,输入在其中运行 Cloud Build 的项目。
      2. 点击证明者名称字段,可看到 built-by-cloud-build 证明者可用。
      3. 点击 built-by-cloud-build
    2. 或者,您也可以选择根据证明者资源 ID 添加。在证明者资源 ID 中,输入 projects/PROJECT_ID/attestors/built-by-cloud-build,并将 PROJECT_ID 替换为在其中运行 Cloud Build 的项目。
  6. 点击添加 1 个证明者 (Add 1 attestor)。

  7. 点击保存政策

gcloud

  1. 使用以下命令将现有政策导出到一个文件中:

    gcloud container binauthz policy export > /tmp/policy.yaml
    
  2. 修改政策文件。

  3. 修改以下规则之一:

    • defaultAdmissionRule
    • clusterAdmissionRules
    • istioServiceIdentityAdmissionRules
    • kubernetesServiceAccountAdmissionRules
  4. 如果还没有 requireAttestationsBy 块,请将其添加到规则中。

  5. requireAttestationsBy 块中,添加 projects/<var>PROJECT_ID</var>/attestors/built-by-cloud-build,并将 PROJECT_ID 替换为在其中运行 Cloud Build 的项目。

  6. 保存政策文件。

  7. 导入政策文件。

    gcloud container binauthz policy import /tmp/policy.yaml
    

    以下是包含对 built-by-cloud-build-attestor 的引用的示例政策文件:

    defaultAdmissionRule:
      evaluationMode: REQUIRE_ATTESTATION
      enforcementMode: ENFORCED_BLOCK_AND_AUDIT_LOG
      requireAttestationsBy:
        - projects/PROJECT_ID/attestors/built-by-cloud-build
    name: projects/PROJECT_ID/policy
    

    PROJECT_ID 替换为运行 Cloud Build 的项目的项目 ID。

您可以在 GKECloud Run 的 Binary Authorization 日志消息中查看政策错误

使用试运行模式

在试运行模式下,Binary Authorization 会检查政策合规性,而不会实际阻止部署。相反,政策合规性状态消息会记录到 Cloud Logging 中。您可以使用这些日志来确定阻止政策是否正常运行以及识别假正例。

如需启用试运行,请执行以下操作:

控制台

  1. 转到 Google Cloud Console 中的“Binary Authorization”页面。

    转到 Binary Authorization

  2. 点击修改政策

  3. 默认规则或特定规则中,选中试运行模式

  4. 点击保存政策

gcloud

  1. 将 Binary Authorization 政策导出到 YAML 文件:

    gcloud container binauthz policy export  > /tmp/policy.yaml
    
  2. 在文本编辑器中,将 enforcementMode 设置为 DRYRUN_AUDIT_LOG_ONLY 并保存文件。

  3. 如需更新政策,请执行以下命令以导入文件:

    gcloud container binauthz policy import /tmp/policy.yaml
    

您可以在 GKECloud Run 的 Binary Authorization 日志消息中查看政策错误

查看证明者元数据

首次在项目中运行构建时,系统会创建 证明者。证明者 ID 为 projects/PROJECT_ID/attestors/built-by-cloud-build。您可以使用以下命令检查构建证明者元数据:

curl -X GET -H "Content-Type: application/json" \
    -H "Authorization: Bearer $(gcloud auth print-access-token)" \
    https://binaryauthorization.googleapis.com/v1beta1/projects/PROJECT_ID/attestors/built-by-cloud-build

PROJECT_ID 替换为运行 Cloud Build 的项目。

输出包含关于证明者和相应公钥的信息。例如:

name": "projects/PROJECT_ID/attestors/built-by-cloud-build",
  "userOwnedDrydockNote": {
    "noteReference": "projects/PROJECT_ID/notes/built-by-cloud-build",
    "publicKeys": [
      {
        "id": "//cloudkms.googleapis.com/v1/projects/verified-builder/locations/asia/keyRings/attestor/cryptoKeys/builtByGCB/cryptoKeyVersions/1",
        "pkixPublicKey": {
          "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMMvFxZLgIiWOLIXsaTkjTmOKcaK7\neIZrgpWHpHziTFGg8qyEI4S8O2/2wh1Eru7+sj0Sh1QxytN/KE5j3mTvYA==\n-----END PUBLIC KEY-----\n",
          "signatureAlgorithm": "ECDSA_P256_SHA256"
        }
      },
...
      }
    ],
    "delegationServiceAccountEmail": "service-942118413832@gcp-binaryauthorization.iam.gserviceaccount.com"
  },
  "updateTime": "2021-09-24T15:26:44.808914Z",
  "description": "Attestor autogenerated by build ID fab07092-30f4-4f70-caf7-4545cbc404d6"

后续步骤