×

Tekton Chains 是一个 Kubernetes 自定义资源定义 (CRD) 控制器。您可以使用它来管理使用 Red Hat OpenShift Pipelines 创建的任务和管道的供应链安全。

默认情况下,Tekton Chains 会观察 OpenShift Container Platform 集群中的所有任务运行执行。任务运行完成后,Tekton Chains 会对任务运行进行快照。然后,它将快照转换为一种或多种标准有效负载格式,最后签署并存储所有工件。

为了捕获有关任务运行的信息,Tekton Chains 使用 `Result` 对象。当对象不可用时,Tekton Chains 使用 OCI 镜像的 URL 和限定摘要。

主要特性

  • 您可以使用诸如 `cosign` 和 `skopeo` 等工具生成的加密密钥来签署任务运行、任务运行结果和 OCI 注册表镜像。

  • 您可以使用诸如 `in-toto` 等证明格式。

  • 您可以使用 OCI 仓库作为存储后端安全地存储签名和已签署的工件。

配置 Tekton Chains

Red Hat OpenShift Pipelines 运算符默认情况下会安装 Tekton Chains。您可以通过修改 `TektonConfig` 自定义资源来配置 Tekton Chains;运算符会自动应用您在此自定义资源中所做的更改。

要编辑自定义资源,请使用以下命令:

$ oc edit TektonConfig config

自定义资源包含一个 `chain:` 数组。您可以向此数组添加任何受支持的配置参数,如下例所示:

apiVersion: operator.tekton.dev/v1alpha1
kind: TektonConfig
metadata:
  name: config
spec:
  addon: {}
  chain:
    artifacts.taskrun.format: tekton
  config: {}

Tekton Chains 配置支持的参数

集群管理员可以使用各种受支持的参数键和值来配置有关任务运行、OCI 镜像和存储的规范。

任务运行工件支持的参数

表 1. Chains 配置:任务运行工件支持的参数
描述 支持的值 默认值

artifacts.taskrun.format

存储任务运行有效负载的格式。

`in-toto`, `slsa/v1`

in-toto

artifacts.taskrun.storage

任务运行签名的存储后端。您可以将多个后端指定为逗号分隔的列表,例如 `“tekton,oci”`。要禁用存储任务运行工件,请提供空字符串 `“”`。

`tekton`, `oci`, `gcs`, `docdb`, `grafeas`

oci

artifacts.taskrun.signer

用于签署任务运行有效负载的签名后端。

`x509`, `kms`

x509

`slsa/v1` 是 `in-toto` 的别名,用于向后兼容。

管道运行工件支持的参数

表 2. Chains 配置:管道运行工件支持的参数
参数 描述 支持的值 默认值

artifacts.pipelinerun.format

存储流水线运行负载的格式。

`in-toto`, `slsa/v1`

in-toto

artifacts.pipelinerun.storage

存储流水线运行签名的存储后端。您可以指定多个后端,以逗号分隔的列表形式,例如 “tekton,oci”。要禁用存储流水线运行工件,请提供空字符串 “”

`tekton`, `oci`, `gcs`, `docdb`, `grafeas`

oci

artifacts.pipelinerun.signer

用于签署流水线运行负载的签名后端。

x509, kms

x509

artifacts.pipelinerun.enable-deep-inspection

当此参数为 true 时,Tekton Chains 会记录流水线运行的子任务运行结果。当此参数为 false 时,Tekton Chains 会记录流水线运行的结果,但不会记录其子任务运行的结果。

"true", "false"

"false"

  • `slsa/v1` 是 `in-toto` 的别名,用于向后兼容。

  • 对于 grafeas 存储后端,仅支持容器分析。在当前版本的 Tekton Chains 中,您无法配置 grafeas 服务器地址。

OCI 工件支持的参数

表 3. Chains 配置:OCI 工件支持的参数
参数 描述 支持的值 默认值

artifacts.oci.format

存储 OCI 负载的格式。

simplesigning

simplesigning

artifacts.oci.storage

存储 OCI 签名的存储后端。您可以指定多个后端,以逗号分隔的列表形式,例如 “oci,tekton”。要禁用存储 OCI 工件,请提供空字符串 “”

`tekton`, `oci`, `gcs`, `docdb`, `grafeas`

oci

artifacts.oci.signer

用于签署 OCI 负载的签名后端。

x509, kms

x509

KMS 签名者支持的参数

表 4. Chains 配置:KMS 签名者支持的参数
参数 描述 支持的值 默认值

signers.kms.kmsref

要在 kms 签名者中使用的 KMS 服务的 URI 引用。

支持的方案:gcpkms://, awskms://, azurekms://, hashivault://。更多详细信息,请参见 Sigstore 文档中的 KMS 支持

存储支持的参数

表 5. Chains 配置:存储支持的参数
参数 描述 支持的值 默认值

storage.gcs.bucket

用于存储的 GCS 存储桶

storage.oci.repository

用于存储 OCI 签名和证明的 OCI 仓库。

如果您将其中一个工件存储后端配置为 oci 并且未定义此键,则 Tekton Chains 会将证明与存储的 OCI 工件本身一起存储。如果您定义此键,则证明不会与 OCI 工件一起存储,而是存储在指定的位置。有关更多信息,请参见 cosign 文档

builder.id

为 in-toto 证明设置的构建器 ID

https://tekton.dev/chains/v2

builddefinition.buildtype

in-toto 证明的构建类型。当此参数为 https://tekton.dev/chains/v2/slsa 时,Tekton Chains 会严格按照 SLSA v1.0 规范记录 in-toto 证明。当此参数为 https://tekton.dev/chains/v2/slsa-tekton 时,Tekton Chains 会记录包含附加信息的 in-toto 证明,例如每个 TaskRunPipelineRun 对象中的标签和注释,并将 PipelineRun 对象中的每个任务添加到 resolvedDependencies 下。

https://tekton.dev/chains/v2/slsa,https://tekton.dev/chains/v2/slsa-tekton

https://tekton.dev/chains/v2/slsa

如果您为任何工件启用了 docdb 存储方法,请配置 docstore 存储选项。有关 go-cloud docstore URI 格式的更多信息,请参见 docstore 包文档。Red Hat OpenShift Pipelines 支持以下 docstore 服务

  • firestore

  • dynamodb

表 6. Chains 配置:docstore 存储支持的参数
参数 描述 支持的值 默认值

storage.docdb.url

指向 docstore 集合的 go-cloud URI 引用。如果为任何工件启用了 docdb 存储方法,则使用此项。

firestore://projects/[PROJECT]/databases/(default)/documents/[COLLECTION]?name_field=name

storage.docdb.mongo-server-url

用于 docdb 存储的 Mongo 服务器 URL 值 (MONGO_SERVER_URL)。此 URL 可以包含身份验证信息。对于生产环境,以纯文本配置提供身份验证信息可能不安全。对于生产环境,请使用替代配置设置 storage.docdb.mongo-server-url-dir

storage.docdb.mongo-server-url-dir

位于名为 MONGO_SERVER_URL 的文件的目录。此文件包含用于 docdb 存储的 Mongo 服务器 URL (MONGO_SERVER_URL)。将此文件作为密钥提供,并按照创建和挂载 Mongo 服务器 URL 密钥中的说明配置此文件的挂载,以用于 Tekton Chains 控制器。

示例值:/tmp/mongo-url

如果您为任何工件启用了 grafeas 存储方法,请配置 Grafeas 存储选项。有关 Grafeas 笔记和事件的更多信息,请参见 Grafeas 概念

要创建事件,Red Hat OpenShift Pipelines 必须首先创建用于链接事件的笔记。Red Hat OpenShift Pipelines 创建两种类型的事件:ATTESTATION 事件和 BUILD 事件。

Red Hat OpenShift Pipelines 使用可配置的 noteid 作为笔记名称的前缀。它为 ATTESTATION 笔记附加后缀 -simplesigning,为 BUILD 笔记附加后缀 -intoto。如果未配置 noteid 字段,Red Hat OpenShift Pipelines 将使用 tekton-<NAMESPACE> 作为前缀。

表 7. Chains 配置:Grafeas 存储支持的参数
参数 描述 支持的值 默认值

storage.grafeas.projectid

位于用于存储事件的 Grafeas 服务器的 OpenShift Container Platform 项目。

storage.grafeas.noteid

可选:用于所有已创建笔记名称的前缀。

无空格的字符串。

storage.grafeas.notehint

可选:Grafeas ATTESTATION 笔记的 human_readable_name 字段。

此证明笔记由 Tekton Chains 生成

您可以选择启用二进制透明度证明的额外上传。

表 8. Chains 配置:透明度证明存储支持的参数
参数 描述 支持的值 默认值

transparency.enabled

启用或禁用自动二进制透明度上传。

true, false, manual

false

transparency.url

如果启用,用于上传二进制透明度证明的 URL。

https://rekor.sigstore.dev

如果您将 transparency.enabled 设置为 manual,则只有具有以下注释的任务运行和流水线运行将上传到透明度日志
chains.tekton.dev/transparency-upload: "true"

如果您配置了 x509 签名后端,则可以选择使用 Fulcio 启用无密钥签名。

表 9. Chains 配置:使用 Fulcio 的 x509 无密钥签名支持的参数
参数 描述 支持的值 默认值

signers.x509.fulcio.enabled

启用或禁用从 Fulcio 自动请求证书。

true, false

false

signers.x509.fulcio.address

如果启用,用于请求证书的 Fulcio 地址。

https://v1.fulcio.sigstore.dev

signers.x509.fulcio.issuer

预期的 OIDC 发行者。

https://oauth2.sigstore.dev/auth

signers.x509.fulcio.provider

从中请求 ID 令牌的提供者。

google, spiffe, github, filesystem

Red Hat OpenShift Pipelines 会尝试使用每个提供者

signers.x509.identity.token.file

包含 ID 令牌的文件路径。

signers.x509.tuf.mirror.url

TUF 服务器的 URL。必须存在 $TUF_URL/root.json

https://sigstore-tuf-root.storage.googleapis.com

如果您配置了 kms 签名后端,请根据需要设置 KMS 配置,包括 OIDC 和 Spire。

表 10. Chains 配置:KMS 签名支持的参数
参数 描述 支持的值 默认值

signers.kms.auth.address

KMS 服务器的 URI (VAULT_ADDR 的值)。

signers.kms.auth.token

KMS服务器的身份验证令牌(VAULT_TOKEN的值)。将令牌作为纯文本配置可能不安全。生产环境中请使用替代的signers.kms.auth.token-path配置设置。

signers.kms.auth.token-path

包含KMS服务器身份验证令牌(VAULT_TOKEN的值)的文件的完整路径名。请将此文件作为密钥提供,并按照创建和挂载KMS身份验证令牌密钥中的说明为Tekton Chains控制器配置挂载此文件。

示例值:/etc/kms-secrets/KMS_AUTH_TOKEN

signers.kms.auth.oidc.path

OIDC身份验证的路径(例如,Vault的jwt)。

signers.kms.auth.oidc.role

OIDC身份验证的角色。

signers.kms.auth.spire.sock

KMS令牌的Spire套接字URI(例如,unix:///tmp/spire-agent/public/api.sock)。

signers.kms.auth.spire.audience

从Spire请求SVID的目标受众。

创建和挂载Mongo服务器URL密钥

您可以使用密钥提供用于docdb存储的Mongo服务器URL的值(MONGO_SERVER_URL)。您必须创建此密钥,将其挂载到Tekton Chains控制器上,并将storage.docdb.mongo-server-url-dir参数设置为挂载密钥的目录。

前提条件
  • 您已安装OpenShift CLI(oc)实用程序。

  • 您已使用openshift-pipelines命名空间的管理员权限登录到您的OpenShift Container Platform集群。

步骤
  1. 创建一个名为mongo-url的密钥,其中包含包含Mongo服务器URL值的MONGO_SERVER_URL文件,方法是输入以下命令:

    $ oc create secret generic mongo-url -n tekton-chains \
      --from-file=MONGO_SERVER_URL=<path>/MONGO_SERVER_URL (1)
    1 包含Mongo服务器URL值的MONGO_SERVER_URL文件的完整路径和名称。
  2. TektonConfig自定义资源(CR)的chain部分中,配置将密钥挂载到Tekton Chains控制器上,并将storage.docdb.mongo-server-url-dir参数设置为挂载密钥的目录,如下例所示:

    挂载mongo-url密钥的示例配置
    apiVersion: operator.tekton.dev/v1
    kind: TektonConfig
    metadata:
      name: config
    spec:
    # ...
      chain:
        disabled: false
        storage.docdb.mongo-server-url-dir: /tmp/mongo-url
        options:
          deployments:
            tekton-chains-controller:
              spec:
                template:
                  spec:
                    containers:
                    - name: tekton-chains-controller
                      volumeMounts:
                      - mountPath: /tmp/mongo-url
                        name: mongo-url
                    volumes:
                    -  name: mongo-url
                       secret:
                        secretName: mongo-url
    # ...

创建和挂载KMS身份验证令牌密钥

您可以使用密钥提供KMS服务器的身份验证令牌。例如,如果KMS提供程序是Hashicorp Vault,则密钥必须包含VAULT_TOKEN的值。

您必须创建此密钥,将其挂载到Tekton Chains控制器上,并将signers.kms.auth.token-path参数设置为身份验证令牌文件的完整路径名。

前提条件
  • 您已安装OpenShift CLI(oc)实用程序。

  • 您已使用openshift-pipelines命名空间的管理员权限登录到您的OpenShift Container Platform集群。

步骤
  1. 创建一个名为kms-secrets的密钥,其中包含包含KMS服务器身份验证令牌的KMS_AUTH_TOKEN文件,方法是输入以下命令:

    $ oc create secret generic kms-secrets -n tekton-chains \
      --from-file=KMS_AUTH_TOKEN=<path_and_name> (1)
    1 包含KMS服务器身份验证令牌的文件的完整路径和名称,例如/home/user/KMS_AUTH_TOKEN。您可以使用其他文件名代替KMS_AUTH_TOKEN
  2. TektonConfig自定义资源(CR)的chain部分中,配置将密钥挂载到Tekton Chains控制器上,并将signers.kms.auth.token-path参数设置为身份验证令牌文件的完整路径名,如下例所示:

    挂载kms-secrets密钥的示例配置
    apiVersion: operator.tekton.dev/v1
    kind: TektonConfig
    metadata:
      name: config
    spec:
    # ...
      chain:
        disabled: false
        signers.kms.auth.token-path: /etc/kms-secrets/KMS_AUTH_TOKEN
        options:
          deployments:
            tekton-chains-controller:
              spec:
                template:
                  spec:
                    containers:
                    - name: tekton-chains-controller
                      volumeMounts:
                      - mountPath: /etc/kms-secrets
                        name: kms-secrets
                    volumes:
                    -  name: kms-secrets
                       secret:
                        secretName: kms-secrets
    # ...

启用Tekton Chains仅在选定命名空间中运行

默认情况下,Tekton Chains控制器监控所有命名空间中的资源。您可以自定义Tekton Chains,使其仅在特定命名空间中运行,这可以提供对其操作的细粒度控制。

前提条件
  • 您已使用cluster-admin权限登录到您的OpenShift Container Platform集群。

步骤
  • TektonConfig CR的chain部分中,添加--namespace=参数以包含控制器应监控的命名空间。

    以下示例显示了Tekton Chains控制器配置,使其仅监控devtest命名空间内的资源,并相应地过滤PipelineRunTaskRun对象:

    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonConfig
    metadata:
      name: config
    spec:
      chain:
        disabled: false
        options:
          deployments:
            tekton-chains-controller:
              spec:
                template:
                  spec:
                    containers:
                    - args:
                      - --namespace=dev, test (1)
                      name: tekton-chains-controller
    1 如果未提供--namespace参数或将其留空,则控制器默认监控所有命名空间。

Tekton Chains中用于签名数据的密钥

集群管理员可以生成密钥对,并使用Tekton Chains使用Kubernetes密钥签名工件。为了使Tekton Chains正常工作,openshift-pipelines命名空间中的signing-secrets密钥中必须存在用于加密密钥的私钥和密码。

目前,Tekton Chains支持x509cosign签名方案。

仅使用一种受支持的签名方案。

x509签名方案

要将x509签名方案与Tekton Chains一起使用,您必须满足以下要求:

  • 将私钥存储在signing-secrets中,结构为x509.pem

  • 将私钥存储为未加密的PKCS #8 PEM文件。

  • 密钥类型为ed25519ecdsa

cosign签名方案

要将cosign签名方案与Tekton Chains一起使用,您必须满足以下要求:

  • 将私钥存储在signing-secrets中,结构为cosign.key

  • 将密码存储在signing-secrets中,结构为cosign.password

  • 将私钥存储为ENCRYPTED COSIGN PRIVATE KEY类型的加密PEM文件。

使用TektonConfig CR生成x509密钥对

要将x509签名方案用于Tekton Chains密钥,您必须生成x509密钥对。

您可以通过将TektonConfig自定义资源(CR)中的generateSigningSecret字段设置为true来生成x509密钥对。Red Hat OpenShift Pipelines Operator会生成一个ecdsa类型的密钥对:一个x509.pem私钥和一个x509-pub.pem公钥。Operator会将密钥存储在openshift-pipelines命名空间中的signing-secrets密钥中。

如果您将generateSigningSecret字段从true设置为false,Red Hat OpenShift Pipelines Operator将覆盖并清空signing-secrets密钥中的任何值。请确保将x509-pub.pem公钥存储在密钥之外,以保护密钥免遭删除。Operator稍后可以使用此密钥来验证工件证明。

Red Hat OpenShift Pipelines Operator不提供以下功能以限制潜在的安全问题:

  • 密钥轮换

  • 密钥使用情况审核

  • 对密钥的适当访问控制

前提条件
  • 您已安装OpenShift CLI(oc)实用程序。

  • 您已使用openshift-pipelines命名空间的管理员权限登录到您的OpenShift Container Platform集群。

步骤
  1. 通过运行以下命令编辑TektonConfig CR:

    $ oc edit TektonConfig config
  2. TektonConfig CR中,将generateSigningSecret值设置为true

    使用TektonConfig CR创建ecdsa密钥对的示例
    apiVersion: operator.tekton.dev/v1
    kind: TektonConfig
    metadata:
      name: config
    spec:
    # ...
      chain:
        disabled: false
        generateSigningSecret: true (1)
    # ...
    1 默认值为false。将值设置为true会生成ecdsa密钥对。

使用cosign工具签名

您可以使用cosign工具,将cosign签名方案与Tekton Chains一起使用。

前提条件
步骤
  1. 通过运行以下命令生成cosign.keycosign.pub密钥对:

    $ cosign generate-key-pair k8s://openshift-pipelines/signing-secrets

    Cosign会提示您输入密码,然后创建一个Kubernetes密钥。

  2. 将加密的cosign.key私钥和cosign.password解密密码存储在signing-secrets Kubernetes密钥中。确保私钥存储为ENCRYPTED COSIGN PRIVATE KEY类型的加密PEM文件。

使用skopeo工具签名

您可以使用skopeo工具生成密钥,并在 Tekton Chains 的cosign签名方案中使用它们。

前提条件
  • 您已安装 skopeo 工具。

步骤
  1. 运行以下命令生成公钥/私钥对:

    $ skopeo generate-sigstore-key --output-prefix <mykey> (1)
    1 <mykey>替换为您选择的密钥名称。

    Skopeo 会提示您输入私钥的密码,然后创建名为<mykey>.private<mykey>.pub 的密钥文件。

  2. 使用base64工具对<mykey>.pub文件进行编码,运行以下命令:

    $ base64 -w 0 <mykey>.pub > b64.pub
  3. 使用base64工具对<mykey>.private文件进行编码,运行以下命令:

    $ base64 -w 0 <mykey>.private > b64.private
  4. 使用base64工具对密码进行编码,运行以下命令:

    $ echo -n '<passphrase>' | base64 -w 0 > b64.passphrase (1)
    1 <passphrase>替换为您为密钥对使用的密码。
  5. openshift-pipelines命名空间中创建signing-secrets密钥,运行以下命令:

    $ oc create secret generic signing-secrets -n openshift-pipelines
  6. 编辑signing-secrets密钥,运行以下命令:

    $ oc edit secret -n openshift-pipelines signing-secrets

    以以下方式在密钥的数据中添加编码后的密钥:

    apiVersion: v1
    data:
      cosign.key: <Encoded <mykey>.private> (1)
      cosign.password: <Encoded passphrase> (2)
      cosign.pub: <Encoded <mykey>.pub> (3)
    immutable: true
    kind: Secret
    metadata:
      name: signing-secrets
    # ...
    type: Opaque
    1 <Encoded <mykey>.private>替换为b64.private文件的内容。
    2 <Encoded passphrase>替换为b64.passphrase文件的内容。
    3 <Encoded <mykey>.pub>替换为b64.pub文件的内容。

解决“密钥已存在”错误

如果signing-secret密钥已填充,则创建此密钥的命令可能会输出以下错误消息:

Error from server (AlreadyExists): secrets "signing-secrets" already exists

您可以通过删除密钥来解决此错误。

步骤
  1. 运行以下命令删除signing-secret密钥:

    $ oc delete secret signing-secrets -n openshift-pipelines
  2. 重新创建密钥对,并使用您首选的签名方案将它们存储在密钥中。

向 OCI 注册表进行身份验证

在将签名推送到 OCI 注册表之前,集群管理员必须配置 Tekton Chains 以对注册表进行身份验证。Tekton Chains 控制器使用任务运行所使用的相同服务帐户。要设置具有将签名推送到 OCI 注册表所需凭据的服务帐户,请执行以下步骤:

步骤
  1. 设置 Kubernetes 服务帐户的命名空间和名称。

    $ export NAMESPACE=<namespace> (1)
    $ export SERVICE_ACCOUNT_NAME=<service_account> (2)
    1 与服务帐户关联的命名空间。
    2 服务帐户的名称。
  2. 创建一个 Kubernetes 密钥。

    $ oc create secret registry-credentials \
      --from-file=.dockerconfigjson \ (1)
      --type=kubernetes.io/dockerconfigjson \
      -n $NAMESPACE
    1 替换为 Docker 配置文件的路径。默认路径为~/.docker/config.json
  3. 使服务帐户能够访问密钥。

    $ oc patch serviceaccount $SERVICE_ACCOUNT_NAME \
      -p "{\"imagePullSecrets\": [{\"name\": \"registry-credentials\"}]}" -n $NAMESPACE

    如果您修补 Red Hat OpenShift Pipelines 分配给所有任务运行的默认pipeline服务帐户,则 Red Hat OpenShift Pipelines 运算符将覆盖该服务帐户。最佳实践是,您可以执行以下步骤:

    1. 创建一个单独的服务帐户以分配给用户的任务运行。

      $ oc create serviceaccount <service_account_name>
    2. 通过设置任务运行模板中serviceaccountname字段的值,将服务帐户与任务运行关联。

      apiVersion: tekton.dev/v1
      kind: TaskRun
      metadata:
        name: build-push-task-run-2
      spec:
        taskRunTemplate:
          serviceAccountName: build-bot (1)
        taskRef:
          name: build-push
      ...
      1 替换为新创建的服务帐户的名称。

无需任何额外身份验证即可创建和验证任务运行签名

要使用 Tekton Chains 验证任务运行的签名而无需任何额外身份验证,请执行以下任务:

  • 生成加密的x509cosign密钥对,并将其存储为 Kubernetes 密钥。

  • 配置 Tekton Chains 后端存储。

  • 创建任务运行,对其进行签名,并将签名和有效负载存储为任务运行本身上的注释。

  • 从已签名的任务运行中检索签名和有效负载。

  • 验证任务运行的签名。

前提条件

确保集群上安装了以下组件:

  • Red Hat OpenShift Pipelines 运算符

  • Tekton Chains

  • Cosign

步骤
  1. 生成加密的x509cosign密钥对。有关创建密钥对并将其保存为密钥的更多信息,请参见“Tekton Chains 中用于签名数据的密钥”。

  2. 在 Tekton Chains 配置中,禁用 OCI 存储,并将任务运行存储和格式设置为tekton。在TektonConfig自定义资源中设置以下值:

    apiVersion: operator.tekton.dev/v1alpha1
    kind: TektonConfig
    metadata:
      name: config
    spec:
    # ...
        chain:
          artifacts.oci.storage: ""
          artifacts.taskrun.format: tekton
          artifacts.taskrun.storage: tekton
    # ...

    有关使用TektonConfig自定义资源配置 Tekton Chains 的更多信息,请参见“配置 Tekton Chains”。

  3. 要重新启动 Tekton Chains 控制器以确保应用修改后的配置,请输入以下命令:

    $ oc delete po -n openshift-pipelines -l app=tekton-chains-controller
  4. 通过输入以下命令创建任务运行:

    $ oc create -f https://raw.githubusercontent.com/tektoncd/chains/main/examples/taskruns/task-output-image.yaml (1)
    1 将示例 URI 替换为您指向任务运行的 URI 或文件路径。
    示例输出:
    taskrun.tekton.dev/build-push-run-output-image-qbjvh created
  5. 输入以下命令检查步骤的状态。等待进程完成。

    $ tkn tr describe --last
    示例输出:
    [...truncated output...]
    NAME                            STATUS
    ∙ create-dir-builtimage-9467f   Completed
    ∙ git-source-sourcerepo-p2sk8   Completed
    ∙ build-and-push                Completed
    ∙ echo                          Completed
    ∙ image-digest-exporter-xlkn7   Completed
  6. 要从存储为base64编码注释的对象中检索签名,请输入以下命令:

    $ tkn tr describe --last -o jsonpath="{.metadata.annotations.chains\.tekton\.dev/signature-taskrun-$TASKRUN_UID}" | base64 -d > sig
    $ export TASKRUN_UID=$(tkn tr describe --last -o  jsonpath='{.metadata.uid}')
  7. 要使用您创建的公钥验证签名,请输入以下命令:

$ cosign verify-blob-attestation --insecure-ignore-tlog --key path/to/cosign.pub --signature sig --type slsaprovenance --check-claims=false /dev/null (1)
1 path/to/cosign.pub替换为公钥文件的路径名。
示例输出:
Verified OK

使用 Tekton Chains 签名和验证镜像和来源

集群管理员可以通过执行以下任务来使用 Tekton Chains 签名和验证镜像和来源:

  • 生成加密的x509cosign密钥对,并将其存储为 Kubernetes 密钥。

  • 设置 OCI 注册表的身份验证,以存储镜像、镜像签名和已签名的镜像声明。

  • 配置 Tekton Chains 以生成和签名来源。

  • 在任务运行中使用 Kaniko 创建镜像。

  • 验证已签名的镜像和已签名的来源。

前提条件

确保集群上安装了以下内容:

  • Red Hat OpenShift Pipelines 运算符

  • Tekton Chains

  • Cosign

  • Rekor

  • jq

步骤
  1. 生成加密的x509cosign密钥对。有关创建密钥对并将其保存为密钥的更多信息,请参见“Tekton Chains 中用于签名数据的密钥”。

  2. 配置镜像注册表的身份验证。

    1. 要配置 Tekton Chains 控制器以将签名推送到 OCI 注册表,请使用与任务运行的服务帐户关联的凭据。有关详细信息,请参见“向 OCI 注册表进行身份验证”部分。

    2. 要为构建并向注册表推送镜像的 Kaniko 任务配置身份验证,请创建包含所需凭据的 docker config.json 文件的 Kubernetes 密钥。

      $ oc create secret generic <docker_config_secret_name> \ (1)
        --from-file <path_to_config.json> (2)
      
      1 替换为 docker config 密钥的名称。
      2 替换为 docker config.json 文件的路径。
  3. 通过设置chains-config对象中的artifacts.taskrun.formatartifacts.taskrun.storagetransparency.enabled参数来配置 Tekton Chains。

    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.format": "in-toto"}}'
    
    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"artifacts.taskrun.storage": "oci"}}'
    
    $ oc patch configmap chains-config -n openshift-pipelines -p='{"data":{"transparency.enabled": "true"}}'
  4. 启动 Kaniko 任务。

    1. 将 Kaniko 任务应用于集群。

      $ oc apply -f examples/kaniko/kaniko.yaml (1)
      1 替换为您 Kaniko 任务的 URI 或文件路径。
    2. 设置适当的环境变量。

      $ export REGISTRY=<url_of_registry> (1)
      
      $ export DOCKERCONFIG_SECRET_NAME=<name_of_the_secret_in_docker_config_json> (2)
      1 替换为您要推送镜像的注册表的 URL。
      2 替换为 docker config.json 文件中密钥的名称。
    3. 启动 Kaniko 任务。

      $ tkn task start --param IMAGE=$REGISTRY/kaniko-chains --use-param-defaults --workspace name=source,emptyDir="" --workspace name=dockerconfig,secret=$DOCKERCONFIG_SECRET_NAME kaniko-chains

      观察此任务的日志,直到所有步骤都完成。身份验证成功后,最终镜像将被推送到$REGISTRY/kaniko-chains

  5. 等待一分钟,让 Tekton Chains 生成来源并对其进行签名,然后检查任务运行上chains.tekton.dev/signed=true注释的可用性。

    $ oc get tr <task_run_name> \ (1)
    -o json | jq -r .metadata.annotations
    
    {
      "chains.tekton.dev/signed": "true",
      ...
    }
    1 替换为任务运行的名称。
  6. 验证镜像和声明。

    $ cosign verify --key cosign.pub $REGISTRY/kaniko-chains
    
    $ cosign verify-attestation --key cosign.pub $REGISTRY/kaniko-chains
  7. 在 Rekor 中查找镜像的来源。

    1. 获取 $REGISTRY/kaniko-chains 镜像的摘要。您可以在任务运行中搜索它,或拉取镜像以提取摘要。

    2. 搜索 Rekor 以查找与镜像的 sha256 摘要匹配的所有条目。

      $ rekor-cli search --sha <image_digest> (1)
      
      <uuid_1> (2)
      <uuid_2> (3)
      ...
      1 替换为镜像的 sha256 摘要。
      2 第一个匹配的通用唯一标识符 (UUID)。
      3 第二个匹配的 UUID。

      搜索结果显示匹配条目的 UUID。其中一个 UUID 包含证明。

    3. 检查证明。

      $ rekor-cli get --uuid <uuid> --format json | jq -r .Attestation | base64 --decode | jq