(可选)零信任签名验证

TIP
  • 如果您对零信任签名验证感兴趣,可以继续阅读以下内容。
  • 本章节内容需要能够访问公网。
  • 如果您已经部署了私有的 Rekor 服务,也可以使用私有服务。
NOTE
  • 此方法要求环境能够访问互联网。
  • 如果您已部署私有的 Rekor 服务,也可以通过调整相关配置使用这些功能。
  • 私有 Rekor 服务的部署不在本文档范围内,请参考相关文档。

虽然 ACP(Alauda Container Platform)当前不支持部署私有 Rekor 实例,但提供了与 Rekor 服务的集成能力。

这里以集成公共 Rekor 服务为例介绍如何使用这些服务。 如果您已部署私有 Rekor 服务,请参考相关文档进行配置。

目录

功能概述

该方法利用透明日志增强安全性,免去了密钥管理的需求:

  1. 配置 Tekton Chains 使用零信任签名。
  2. 使用 buildah Tekton 任务构建镜像。
  3. 配置 Kyverno 规则验证零信任签名。
  4. 使用镜像创建 Pod 以验证零信任签名。

使用场景

以下场景需要参考本文档指导:

  • 在 Kubernetes 集群中实现容器镜像的零信任签名与验证
  • 强制执行安全策略以验证镜像签名,无需管理签名密钥
  • 在 CI/CD 流水线中设置自动透明日志验证
  • 通过 Rekor 透明日志确保镜像来源和完整性
  • 通过验证镜像签名与公共 Rekor 服务对接,实现供应链安全控制

前提条件

  • 已安装 Tekton Pipelines、Tekton Chains 和 Kyverno 的 Kubernetes 集群
  • 支持镜像推送的镜像仓库
  • 已安装并配置好访问集群的 kubectl CLI
  • 已安装 cosign CLI 工具
  • 已安装 jq CLI 工具
  • 已安装 curl
  • 已安装 rekor-cli
    • 用于验证和交互存储在 Rekor 透明日志服务器中的证明。

流程概览

步骤操作说明
1生成签名密钥使用 cosign 创建用于签名工件的密钥对
2设置认证配置镜像仓库凭据以支持镜像推送
3配置 Tekton Chains设置 Chains 使用 OCI 存储并配置签名
4重新运行流水线触发新的流水线运行以生成透明日志条目
5获取 Rekor 日志索引从 PipelineRun 注解中提取 Rekor 日志索引
6使用 curl 验证 Rekor 签名使用 curl 获取并验证 Rekor 签名
7使用 Rekor CLI使用 rekor-cli 工具获取并验证签名
8在 Kyverno 中验证 Rekor配置 Kyverno 策略进行 Rekor 验证

逐步操作指南

步骤 1-3:基础设置

这些步骤与快速开始:签名溯源指南相同。请按照该指南完成:

TIP
  • 如果您有私有 Rekor 服务,可以将 transparency.url 设置为您的 Rekor 服务器地址。
    • transparency.url: "<https://rekor.sigstore.dev>"

更多配置详情,请参考 Transparency Log

步骤 4:重新运行流水线生成镜像

TIP
  • 由于修改了透明日志配置,需要在签名溯源中触发新的流水线运行。
  • 这样 Tekton Chains 才能为新的镜像和 PipelineRun 生成透明日志条目。

步骤 5:获取 Rekor 日志索引

从 PipelineRun 的注解中获取 Rekor 日志索引。

$ export NAMESPACE=<pipeline-namespace>
$ export PIPELINERUN_NAME=<pipelinerun-name>
$ kubectl get pipelinerun -n $NAMESPACE $PIPELINERUN_NAME -o jsonpath='{.metadata.annotations.chains\.tekton\.dev/transparency}'

https://rekor.sigstore.dev/api/v1/log/entries?logIndex=232330257

步骤 6:使用 curl 获取 Rekor 签名

$ curl -s "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=232330257" | jq

如果需要查看 Rekor 签名的内容,可以执行以下命令:

$ curl -s "https://rekor.sigstore.dev/api/v1/log/entries?logIndex=232330257" | jq -r '.[keys[0]].attestation.data | @base64d' | jq .

{
  "_type": "https://in-toto.io/Statement/v0.1",
  "subject": null,
  "predicateType": "https://slsa.dev/provenance/v0.2",
  "predicate": {
    "buildType": "tekton.dev/v1beta1/PipelineRun",
    "builder": {
      "id": "https://alauda.io/builders/tekton/v1"
    },
    "materials": [
      {
        "digest": {
          "sha256": "8d5ea9ecd9b531e798fecd87ca3b64ee1c95e4f2621d09e893c58ed593bfd4c4"
        },
        "uri": "oci://<registry>/devops/tektoncd/hub/buildah"
      }
    ],
    "metadata": {
      "buildFinishedOn": "2025-06-08T03:11:52Z",
      "buildStartedOn": "2025-06-08T03:10:33Z"
    }
  }
}

该内容与镜像中的证明一致,用于验证镜像内容的真实性和完整性。 证明信息可从 Rekor 获取,无需镜像仓库凭据,方便验证。

步骤 7:使用 rekor-cli 获取 Rekor 签名

通过日志索引获取签名

# 日志索引与 PipelineRun 注解中一致
$ rekor-cli get --log-index 232330257 --format json | jq -r .Attestation | jq .

通过镜像摘要获取签名

# 通过镜像摘要获取 uuid
$ rekor-cli search --sha da4885861a8304abad71fcdd569c92daf33422073d1102013a1fed615dfb285a

Found matching entries (listed by UUID):
108e9186e8c5677a1364e68001a916d3a7316bc2580bd6b5fbbce39a9c62f13282d3e974a6b434ab

# 通过 uuid 获取签名
$ rekor-cli get --uuid 108e9186e8c5677a1364e68001a916d3a7316bc2580bd6b5fbbce39a9c62f13282d3e974a6b434ab --format json | jq -r .Attestation | jq .

步骤 8:在 Kyverno 中验证 Rekor

修改 ClusterPolicykeys 部分,添加 Rekor 验证配置。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
spec:
  rules:
    - name: check-image
      verifyImages:
        - attestors:
            - count: 1
              entries:
                - keys:
                    publicKeys: |- # <- 签名者的公钥
                      -----BEGIN PUBLIC KEY-----
                      MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFZNGfYwn7+b4uSdEYLKjxWi3xtP3
                      UkR8hQvGrG25r0Ikoq0hI3/tr0m7ecvfM75TKh5jGAlLKSZUJpmCGaTToQ==
                      -----END PUBLIC KEY-----

                    rekor:
                      ignoreTlog: false
                      # url: <https://rekor.sigstore.dev>
                      # # 从 rekor 服务器获取公钥
                      # # curl <https://rekor.sigstore.dev>/api/v1/log/publicKey
                      # pubkey: |-
                      #   -----BEGIN PUBLIC KEY-----
                      #   MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE2G2Y+2tabdTV5BcGiBIx0a9fAFwr
                      #   kBbmLSGtks4L3qX6yYY0zufBnhC8Ur/iy55GhWP/9A/bY2LhC30M9+RYtw==
                      #   -----END PUBLIC KEY-----
YAML 字段说明
  • rekor:Rekor 验证配置。
    • ignoreTlog:是否忽略透明日志。
      • 若为 false,则会验证 rekor 服务器。
    • url:rekor 服务器的 URL。
      • 若未设置,默认使用 https://rekor.sigstore.dev
    • pubkey:签名者的公钥。
      • 若未设置,将从 rekor 服务器获取公钥。
      • 如果 rekor 服务器是私有的,需要从服务器获取公钥。
        • curl <https://rekor.sigstore.dev>/api/v1/log/publicKey

如果镜像未签名,Pod 会被阻止创建。

Error from server: admission webhook "mutate.kyverno.svc-fail" denied the request:

resource Pod/policy/sign was blocked due to the following policies

only-cosign-image-deploy:
  check-image: 'failed to verify image <registry>/test/chains/demo-1:latest:
    .attestors[0].entries[0].keys: no matching signatures: searching log query: Post
    "http:///api/v1/log/entries/retrieve": POST http:///api/v1/log/entries/retrieve
    giving up after 4 attempt(s): Post "http:///api/v1/log/entries/retrieve": http:
    no Host in request URL'

预期结果

完成本指南后:

  • 您已成功搭建了支持零信任签名和 Rekor 集成的 Tekton Chains 环境
  • 容器镜像会自动签名,签名存储于 Rekor 透明日志中
  • 可以无需管理签名密钥验证镜像签名
  • 只有在 Rekor 中具有有效签名的镜像才能在指定命名空间中部署
  • 通过 Rekor 验证镜像签名,实现了零信任供应链安全控制

本指南为在 CI/CD 流水线中实现零信任签名与验证提供了基础。在生产环境中,您应当:

  1. 配置合适的命名空间隔离和访问控制
  2. 设置签名验证失败的监控和告警
  3. 定期审查和更新安全策略
  4. 考虑部署私有 Rekor 实例以增强安全性

参考资料