Vulnerability Scanning and Verification

在 ACP(Alauda Container Platform)中,您可以使用 Tekton Pipeline 来构建镜像并扫描漏洞。

具体来说,使用 trivy 任务生成漏洞扫描结果,然后使用 cosign 上传漏洞扫描结果的证明,最后使用 kyverno 验证漏洞扫描结果的证明。

目录

功能概述

此方法使用类似 trivy 的工具扫描镜像漏洞,然后使用 Kyverno 验证漏洞扫描结果:

  1. 使用 trivy Tekton 任务扫描镜像漏洞。
  2. 使用 cosign Tekton 任务上传漏洞扫描结果到镜像。
  3. 配置 Kyverno 规则验证漏洞扫描结果。
  4. 使用该镜像创建 Pod 以验证漏洞扫描结果。

使用场景

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

  • 在 Kubernetes 集群中使用 Kyverno 实现漏洞扫描和验证
  • 强制安全策略,仅允许漏洞等级可接受的镜像部署
  • 在 CI/CD 流水线中设置自动漏洞扫描和验证
  • 确保生产环境中镜像的安全性和漏洞合规性
  • 通过验证容器镜像的漏洞状态,实现供应链安全控制

前提条件

  • 已安装 Tekton Pipelines、Tekton Chains 和 Kyverno 的 Kubernetes 集群
  • 支持镜像推送的镜像仓库
  • 已安装并配置好访问集群的 kubectl CLI
  • 已安装 cosign CLI 工具
  • 已安装 jq CLI 工具

流程概述

步骤操作说明
1生成签名密钥使用 cosign 创建用于签名工件的密钥对
2设置认证配置镜像推送的仓库凭证
3配置 Tekton Chains设置 Chains 使用 OCI 存储并配置签名,禁用 TaskRun SLSA Provenance
4创建示例流水线创建包含 trivy 扫描器和 cosign 上传任务的流水线定义
5运行示例流水线创建并运行配置正确的 PipelineRun
6等待签名等待 PipelineRun 被 Chains 签名
7获取镜像信息从 PipelineRun 中提取镜像 URI 和摘要
8(可选)获取漏洞证明获取并验证漏洞扫描证明
9使用 Kyverno 验证创建并应用 Kyverno 策略验证漏洞扫描结果
10(可选)要求扫描时效添加条件要求漏洞扫描结果必须在 168 小时内
11清理资源删除测试资源和策略

逐步操作指南

步骤 1-3:基础设置

这些步骤与快速开始:签名溯源指南相同。请按照该指南中的说明操作:

步骤 4:创建示例流水线

这是一个 Pipeline 资源,用于构建镜像并生成 cosign 漏洞证明。

apiVersion: tekton.dev/v1
kind: Pipeline
metadata:
  name: chains-demo-4
spec:
  params:
    - default: |-
        echo "Generate a Dockerfile for building an image."

        cat << 'EOF' > Dockerfile
        FROM ubuntu:latest
        ENV TIME=1
        EOF

        echo -e "\nDockerfile contents:"
        echo "-------------------"
        cat Dockerfile
        echo "-------------------"
        echo -e "\nDockerfile generated successfully!"
      description: A script to generate a Dockerfile for building an image.
      name: generate-dockerfile
      type: string
    - default: <registry>/test/chains/demo-4:latest
      description: The target image address built
      name: image
      type: string
  results:
    - description: first image artifact output
      name: first_image_ARTIFACT_OUTPUTS
      type: object
      value:
        digest: $(tasks.build-image.results.IMAGE_DIGEST)
        uri: $(tasks.build-image.results.IMAGE_URL)
  tasks:
    - name: generate-dockerfile
      params:
        - name: script
          value: $(params.generate-dockerfile)
      taskRef:
        params:
          - name: kind
            value: task
          - name: catalog
            value: catalog
          - name: name
            value: run-script
          - name: version
            value: "0.1"
        resolver: hub
      timeout: 30m0s
      workspaces:
        - name: source
          workspace: source
    - name: build-image
      params:
        - name: IMAGES
          value:
            - $(params.image)
        - name: TLS_VERIFY
          value: "false"
      runAfter:
        - generate-dockerfile
      taskRef:
        params:
          - name: kind
            value: task
          - name: catalog
            value: catalog
          - name: name
            value: buildah
          - name: version
            value: "0.9"
        resolver: hub
      timeout: 30m0s
      workspaces:
        - name: source
          workspace: source
        - name: dockerconfig
          workspace: dockerconfig
    - name: trivy-scanner
      params:
        - name: COMMAND
          value: |-
            set -x

            mkdir -p .git

            # support for insecure registry
            export TRIVY_INSECURE=true

            echo "generate cyclonedx sbom"
            trivy image --skip-db-update --skip-java-db-update --scanners vuln --format cyclonedx --output .git/sbom-cyclonedx.json $(tasks.build-image.results.IMAGE_URL)@$(tasks.build-image.results.IMAGE_DIGEST)
            cat .git/sbom-cyclonedx.json

            echo "trivy scan vulnerabilities based on cyclonedx sbom"
            trivy sbom --skip-db-update --skip-java-db-update --format cosign-vuln --output .git/trivy-scan-result.json .git/sbom-cyclonedx.json
            cat .git/trivy-scan-result.json

            echo "trivy scan vulnerabilities based on cyclonedx sbom and output in table format"
            trivy sbom --skip-db-update --skip-java-db-update --format table .git/sbom-cyclonedx.json
      runAfter:
        - build-image
      taskRef:
        params:
          - name: kind
            value: task
          - name: catalog
            value: catalog
          - name: name
            value: trivy-scanner
          - name: version
            value: "0.4"
        resolver: hub
      timeout: 30m0s
      workspaces:
        - name: source
          workspace: source
        - name: dockerconfig
          workspace: dockerconfig
    - name: cosign-uploads
      params:
        - name: COMMAND
          value: |-
            set -x

            export COSIGN_ALLOW_INSECURE_REGISTRY=true
            export COSIGN_TLOG_UPLOAD=false
            export COSIGN_KEY=$(workspaces.signkey.path)/cosign.key

            echo "Signing image vuln"
            cosign attest --type vuln --predicate .git/trivy-scan-result.json $(tasks.build-image.results.IMAGE_URL)@$(tasks.build-image.results.IMAGE_DIGEST)

            echo "Signing image sbom"
            cosign attest --type cyclonedx --predicate .git/sbom-cyclonedx.json $(tasks.build-image.results.IMAGE_URL)@$(tasks.build-image.results.IMAGE_DIGEST)
      runAfter:
        - trivy-scanner
      taskRef:
        params:
          - name: kind
            value: task
          - name: catalog
            value: catalog
          - name: name
            value: cosign
          - name: version
            value: "0.1"
        resolver: hub
      timeout: 30m0s
      workspaces:
        - name: source
          workspace: source
        - name: dockerconfig
          workspace: dockerconfig
        - name: signkey
          workspace: signkey
  workspaces:
    - name: source
      description: The workspace for source code.
    - name: dockerconfig
      description: The workspace for Docker configuration.
    - name: signkey
      description: The workspace for private keys and passwords used for image signatures.
TIP

本教程通过在流水线内联生成 Dockerfilegit-clone 任务输出,演示了简化的工作流程。 在生产环境中,通常会:

  1. 使用 git-clone 任务从代码仓库拉取源代码
  2. 使用源代码中的 Dockerfile 构建镜像
  3. 这样可以确保版本控制的正确性,并保持代码与流水线配置的分离
YAML 字段说明
  • 步骤 4:创建示例流水线相同,但增加了以下内容:
    • workspaces:
      • signkey:用于镜像签名的私钥和密码的工作空间。
    • tasks:
      • trivy-scanner:扫描镜像漏洞的任务。
      • cosign-uploads:上传漏洞扫描结果证明的任务。

保存为 chains-demo-4.yaml 文件,并执行:

$ export NAMESPACE=<default>

# 在命名空间中创建流水线
$ kubectl create -n $NAMESPACE -f chains-demo-4.yaml

pipeline.tekton.dev/chains-demo-4 created

步骤 5:运行示例流水线

这是一个 PipelineRun 资源,用于运行流水线。

apiVersion: tekton.dev/v1
kind: PipelineRun
metadata:
  generateName: chains-demo-4-
spec:
  pipelineRef:
    name: chains-demo-4
  taskRunTemplate:
    serviceAccountName: <default>
  workspaces:
    - name: dockerconfig
      secret:
        secretName: <registry-credentials>
    - name: signkey
      secret:
        secretName: <signing-secrets>
    - name: source
      volumeClaimTemplate:
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 1Gi
          storageClassName: <nfs>
YAML 字段说明

保存为 chains-demo-4.pipelinerun.yaml 文件,并执行:

$ export NAMESPACE=<default>

# 在命名空间中创建 PipelineRun
$ kubectl create -n $NAMESPACE -f chains-demo-4.pipelinerun.yaml

等待 PipelineRun 完成。

$ kubectl get pipelinerun -n $NAMESPACE -w

chains-demo-4-<xxxxx>     True        Succeeded   2m  2m

步骤 6:等待 PipelineRun 被签名

等待 PipelineRun 拥有 chains.tekton.dev/signed: "true" 注解。

$ export NAMESPACE=<default>
$ export PIPELINERUN_NAME=<chains-demo-4-xxxxx>

$ kubectl get pipelinerun -n $NAMESPACE $PIPELINERUN_NAME -o yaml | grep "chains.tekton.dev/signed"

    chains.tekton.dev/signed: "true"

当 PipelineRun 拥有该注解时,表示镜像已被签名。

步骤 7:从 PipelineRun 获取镜像信息

# 获取镜像 URI
$ export IMAGE_URI=$(kubectl get pipelinerun -n $NAMESPACE $PIPELINERUN_NAME -o jsonpath='{.status.results[?(@.name=="first_image_ARTIFACT_OUTPUTS")].value.uri}')

# 获取镜像摘要
$ export IMAGE_DIGEST=$(kubectl get pipelinerun -n $NAMESPACE $PIPELINERUN_NAME -o jsonpath='{.status.results[?(@.name=="first_image_ARTIFACT_OUTPUTS")].value.digest}')

# 组合镜像 URI 和摘要,形成完整镜像引用
$ export IMAGE=$IMAGE_URI@$IMAGE_DIGEST

# 输出镜像引用
$ echo $IMAGE

<registry>/test/chains/demo-4:latest@sha256:93635f39cb31de5c6988cdf1f10435c41b3fb85570c930d51d41bbadc1a90046

该镜像将用于验证漏洞扫描结果。

步骤 8:(可选)获取 cosign 漏洞证明

TIP

如果您对 cosign 漏洞证明内容感兴趣,可以继续阅读以下内容。

更多关于 cosign 漏洞证明的详情,请参考 cosign vuln attestation

根据获取签名公钥章节获取签名公钥。

# 禁用 tlog 上传并启用私有基础设施
$ export COSIGN_TLOG_UPLOAD=false
$ export COSIGN_PRIVATE_INFRASTRUCTURE=true

$ export IMAGE=<<registry>/test/chains/demo-4:latest@sha256:5e7b466e266633464741b61b9746acd7d02c682d2e976b1674f924aa0dfa2047>

$ cosign verify-attestation --key cosign.pub --type vuln $IMAGE | jq -r '.payload | @base64d' | jq -s

输出类似如下,包含漏洞扫描结果。

cosign 漏洞证明
{
  "_type": "https://in-toto.io/Statement/v0.1",
  "predicateType": "https://cosign.sigstore.dev/attestation/vuln/v1",
  "predicate": {
    "scanner": {
      "uri": "pkg:github/aquasecurity/trivy@dev",
      "version": "dev",
      "result": {
        "CreatedAt": "2025-06-07T07:05:30.098889688Z",
        "Metadata": {
          "OS": {
            "Family": "ubuntu",
            "Name": "24.04"
          }
        },
        "Results": [
          {
            "Class": "os-pkgs",
            "Packages": [
              {
                "Arch": "amd64",
                "ID": "coreutils@9.4-3ubuntu6",
                "Identifier": {
                  "BOMRef": "pkg:deb/ubuntu/coreutils@9.4-3ubuntu6?arch=amd64&distro=ubuntu-24.04",
                  "PURL": "pkg:deb/ubuntu/coreutils@9.4-3ubuntu6?arch=amd64&distro=ubuntu-24.04",
                  "UID": "82bb3c93286700bc"
                },
                "Licenses": [
                  "GPL-3.0-or-later",
                  "BSD-4-Clause-UC",
                  "GPL-3.0-only",
                  "ISC",
                  "FSFULLR",
                  "GFDL-1.3-no-invariants-only",
                  "GFDL-1.3-only"
                ],
                "Name": "coreutils"
              }
            ],
            "Vulnerabilities": [
              {
                "CVSS": {
                  "nvd": {
                    "V2Score": 2.1,
                    "V2Vector": "AV:L/AC:L/Au:N/C:N/I:P/A:N",
                    "V3Score": 6.5,
                    "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:C/C:N/I:H/A:N"
                  },
                  "redhat": {
                    "V2Score": 6.2,
                    "V2Vector": "AV:L/AC:H/Au:N/C:C/I:C/A:C",
                    "V3Score": 8.6,
                    "V3Vector": "CVSS:3.0/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:H"
                  }
                },
                "InstalledVersion": "9.4-3ubuntu6",
                "LastModifiedDate": "2025-04-20T01:37:25.86Z",
                "PkgID": "coreutils@9.4-3ubuntu6",
                "PkgName": "coreutils",
                "PublishedDate": "2017-02-07T15:59:00.333Z",
                "References": [
                  "http://seclists.org/oss-sec/2016/q1/452",
                  "http://www.openwall.com/lists/oss-security/2016/02/28/2",
                  "http://www.openwall.com/lists/oss-security/2016/02/28/3",
                  "https://access.redhat.com/security/cve/CVE-2016-2781",
                  "https://lists.apache.org/thread.html/rf9fa47ab66495c78bb4120b0754dd9531ca2ff0430f6685ac9b07772%40%3Cdev.mina.apache.org%3E",
                  "https://lore.kernel.org/patchwork/patch/793178/",
                  "https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/v2.28/v2.28-ReleaseNotes",
                  "https://nvd.nist.gov/vuln/detail/CVE-2016-2781",
                  "https://www.cve.org/CVERecord?id=CVE-2016-2781"
                ],
                "Severity": "LOW",
                "SeveritySource": "ubuntu",
                "Status": "affected",
                "VendorSeverity": {
                  "azure": 2,
                  "cbl-mariner": 2,
                  "nvd": 2,
                  "redhat": 2,
                  "ubuntu": 1
                },
                "VulnerabilityID": "CVE-2016-2781"
              }
            ]
          }
        ],
        "SchemaVersion": 2
      }
    },
    "metadata": {
      "scanStartedOn": "2025-06-07T07:05:30.104726629Z",
      "scanFinishedOn": "2025-06-07T07:05:30.104726629Z"
    }
  }
}
字段说明
  • predicateType:谓词类型。
  • predicate.scanner
    • uri:扫描器的 URI。
    • version:扫描器版本。
    • result:漏洞扫描结果。
      • CreatedAt:漏洞扫描完成时间。
      • Metadata
        • OS
          • Family:操作系统家族。
          • Name:操作系统名称。
      • Results:漏洞扫描结果。
        • Class
          • os-pkgs:操作系统包。
          • lang-pkgs:语言包。
        • Packages:镜像中的包。
        • Vulnerabilities:镜像中的漏洞。
          • Severity:漏洞严重等级。
          • PkgID:漏洞对应的包 ID。
          • PkgName:漏洞对应的包名。
          • CVSS:漏洞的 CVSS 评分。
            • nvd:NVD 评分。
            • redhat:Red Hat 评分。

步骤 9:使用 Kyverno 验证漏洞扫描结果

步骤 9.1:创建 Kyverno 策略,拒绝高风险漏洞镜像

TIP

此步骤需要集群管理员权限。

更多关于 Kyverno ClusterPolicy,请参考 Kyverno ClusterPolicy

策略如下:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: reject-high-risk-image
spec:
  webhookConfiguration:
    failurePolicy: Fail
    timeoutSeconds: 30
  background: false
  rules:
    - name: check-image
      match:
        any:
          - resources:
              kinds:
                - Pod
              namespaces:
                - policy
      verifyImages:
        - imageReferences:
            - "*"
            # - "<registry>/test/*"
          skipImageReferences:
            - "ghcr.io/trusted/*"
          failureAction: Enforce
          verifyDigest: false
          required: false
          useCache: false
          imageRegistryCredentials:
            allowInsecureRegistry: true
            secrets:
              # 该凭证需存在于 Kyverno 部署的命名空间中
              - registry-credentials

          attestations:
            - type: https://cosign.sigstore.dev/attestation/vuln/v1
              attestors:
                - entries:
                    - attestor:
                      keys:
                        publicKeys: |- # <- 签名者的公钥
                          -----BEGIN PUBLIC KEY-----
                          MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEFZNGfYwn7+b4uSdEYLKjxWi3xtP3
                          UkR8hQvGrG25r0Ikoq0hI3/tr0m7ecvfM75TKh5jGAlLKSZUJpmCGaTToQ==
                          -----END PUBLIC KEY-----

                        ctlog:
                          ignoreSCT: true

                        rekor:
                          ignoreTlog: true

              conditions:
                - all:
                    - key: "{{ scanner.result.Results[].Vulnerabilities[].Severity }}"
                      operator: AllNotIn
                      # 支持值:UNKNOWN, LOW, MEDIUM, HIGH, CRITICAL
                      value: ["HIGH", "CRITICAL"]
                      message: |
                        镜像包含高风险漏洞,请修复后再继续。
                        严重等级:{{ scanner.result.Results[].Vulnerabilities[].Severity }}

                    - key: "{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `1.0`][] | length(@) }}"
                      operator: Equals
                      value: 0
                      message: |
                        镜像包含高风险漏洞,请修复后再继续。
                        高风险漏洞(CVSS > 1.0):{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `1.0`].CVSS.redhat.V3Score[] }}。
                        严重等级:{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `1.0`].Severity[] }}。
                        包 ID:{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `1.0`].PkgID[] }}。
YAML 字段说明
  • 策略与镜像签名验证中大致相同
  • spec.rules[0].verifyImages[].attestations[0].conditions
    • type:cosign 漏洞证明类型为 https://cosign.sigstore.dev/attestation/vuln/v1
    • attestors:同上
    • conditions:需要验证的条件
      • all:所有条件必须满足
        • key: "{{ scanner.result.Results[].Vulnerabilities[].Severity }}":漏洞严重等级不能为 HIGHCRITICAL
        • key: "{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > 1.0][] | length(@) }}":CVSS 分数大于 1.0 的漏洞数量必须为 0

将策略保存为 kyverno.reject-high-risk-image.yaml,并执行:

$ kubectl apply -f kyverno.reject-high-risk-image.yaml

clusterpolicy.kyverno.io/reject-high-risk-image configured

步骤 9.2:验证策略

在定义策略的 policy 命名空间中,创建 Pod 以验证策略。

使用构建好的镜像创建 Pod。

$ export NAMESPACE=<policy>
$ export IMAGE=<<registry>/test/chains/demo-4:latest@sha256:0f123204c44969876ed12f40066ccccbfd68361f68c91eb313ac764d59428bef>

$ kubectl run -n $NAMESPACE vuln-image --image=${IMAGE} -- sleep 3600

如果镜像存在高风险漏洞,Pod 会被策略阻止。 输出类似如下:

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

resource Pod/policy/high-risk was blocked due to the following policies

reject-high-risk-image:
  check-image: |
    image attestations verification failed, verifiedCount: 0, requiredCount: 1, error: .attestations[0].attestors[0].entries[0].keys: attestation checks failed for <registry>/test/chains/demo-4:latest and predicate https://cosign.sigstore.dev/attestation/vuln/v1: The image contains high-risk vulnerabilities, please fix them before proceeding.
    High-risk vulnerabilities (CVSS > 1.0): [8.6,2.7,6.2,5.9,7.5,4.7,7.4,4.7,7.4,4.7,7.4,4.7,7.4,5.9,3.6,3.6,7.3,4.4,6.5,5.4].
    Severity levels: ["LOW","MEDIUM","LOW","LOW","MEDIUM","MEDIUM","MEDIUM","MEDIUM","MEDIUM","MEDIUM","MEDIUM","MEDIUM","MEDIUM","LOW","LOW","LOW","MEDIUM","MEDIUM","MEDIUM","MEDIUM"].
    PkgIDs: ["coreutils@9.4-3ubuntu6","gpgv@2.4.4-2ubuntu17","gpgv@2.4.4-2ubuntu17","libgcrypt20@1.10.3-2build1","liblzma5@5.6.1+really5.4.5-1build0.1","libpam-modules@1.5.3-5ubuntu5.1","libpam-modules@1.5.3-5ubuntu5.1","libpam-modules-bin@1.5.3-5ubuntu5.1","libpam-modules-bin@1.5.3-5ubuntu5.1","libpam-runtime@1.5.3-5ubuntu5.1","libpam-runtime@1.5.3-5ubuntu5.1","libpam0g@1.5.3-5ubuntu5.1","libpam0g@1.5.3-5ubuntu5.1","libssl3t64@3.0.13-0ubuntu3.5","login@1:4.13+dfsg1-4ubuntu3.2","passwd@1:4.13+dfsg1-4ubuntu3.2","perl-base@5.38.2-3.2build2.1","golang.org/x/net@v0.23.0","golang.org/x/net@v0.23.0","stdlib@v1.22.12"].

ClusterPolicy 中的条件修改为允许存在高风险漏洞,但 CVSS 分数小于 10.0 的镜像。

conditions:
  - all:
      - key: "{{ scanner.result.Results[].Vulnerabilities[].Severity }}"
        operator: AllNotIn
        value: ["CRITICAL"]
        message: |
          镜像包含高风险漏洞,请修复后再继续。
          严重等级:{{ scanner.result.Results[].Vulnerabilities[].Severity }}

      - key: "{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `10.0`][] | length(@) }}"
        operator: Equals
        value: 0
        message: |
          镜像包含高风险漏洞,请修复后再继续。
          高风险漏洞(CVSS > 10.0):{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `10.0`].CVSS.redhat.V3Score[] }}。
          严重等级:{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `10.0`].Severity[] }}。
          包 ID:{{ scanner.result.Results[].Vulnerabilities[?CVSS.redhat.V3Score > `10.0`].PkgID[] }}。

然后再次创建 Pod 验证策略。

$ kubectl run -n $NAMESPACE vuln-image --image=${IMAGE} -- sleep 3600

Pod 将成功创建。

步骤 10:(可选)要求漏洞扫描结果必须在 168 小时内

TIP

如果您想为策略添加更多条件,可以继续阅读以下内容。

由于Cosign 漏洞扫描记录证明包含 scanFinishedOn 字段, 且 trivy 符合该规范,我们可以使用该字段判断漏洞扫描结果是否在 168 小时内。

只需在 ClusterPolicy 中添加条件,检查 scanFinishedOn 字段是否在 168 小时内。

conditions:
  - all:
      - key: "{{ time_since('','{{metadata.scanFinishedOn}}','') }}"
        operator: LessThanOrEquals
        value: "168h"
        message: "漏洞扫描结果必须在 168 小时内,当前为 {{ metadata.scanFinishedOn }}"

此处不做演示,有兴趣的读者可自行尝试。

步骤 11:清理资源

删除前面步骤创建的 Pod。

$ export NAMESPACE=<policy>
$ kubectl delete pod -n $NAMESPACE vuln-image

删除策略。

$ kubectl delete clusterpolicy reject-high-risk-image

预期结果

完成本指南后:

  • 您已成功搭建了基于 Tekton Chains 的漏洞扫描和基于 Kyverno 的漏洞验证环境
  • 容器镜像自动包含漏洞扫描结果的证明
  • 仅允许漏洞等级可接受的镜像在指定命名空间中部署
  • 高风险漏洞镜像被 Kyverno 策略自动阻止
  • 通过验证容器镜像漏洞状态,实现了基础的供应链安全控制

本指南为在 CI/CD 流水线中实现供应链安全提供了基础。在生产环境中,您应当:

  1. 配置合理的命名空间隔离和访问控制
  2. 实施安全的签名密钥管理
  3. 设置策略违规的监控和告警
  4. 定期轮换签名密钥并更新安全策略

参考资料