首页
/ Trivy CI/CD 集成全景:用官方与社区管道工具构建 DevSecOps 扫描门禁

Trivy CI/CD 集成全景:用官方与社区管道工具构建 DevSecOps 扫描门禁

2026-09-05 13:15:31作者:郁楠烈Hubert

本篇技术指南基于 Trivy 官方文档 CI/CD Integrations,系统梳理 Trivy 接入各类 CI/CD 平台的集成方式,涵盖 Azure DevOps、GitHub Actions、CircleCI、Woodpecker CI、Concourse CI、Dagger、Semaphore、Buildkite 等官方与社区方案。读完后你将能够:为所用平台选择合适的 Trivy 集成组件,理解 --exit-code 等关键参数如何将扫描结果转化为流水线门禁,并掌握在管道配置中落地可复制的 Trivy 扫描 Job 的通用模式。

Trivy 在 CI/CD 生态中的位置

Trivy 是面向容器、Kubernetes、代码仓库和云环境的开源安全扫描器,可检测漏洞、错误配置、密钥泄露并生成 SBOM。在 DevSecOps 流程中,Trivy 的价值不只在于"能扫",更在于"能接入"——官方文档将 CI/CD 平台集成作为独立生态章节(docs/ecosystem/cicd.md),说明其设计目标之一就是作为流水线中的一等公民:扫描结果通过退出码控制流水线成败,通过报告格式(JSON、SARIF、模板化输出)喂给平台的报表 UI。

官方文档列出的集成按"官方(Official)/社区(Community)"两类组织,完整清单如下:

平台 集成组件 类型 能力概述
Azure DevOps Azure DevOps Pipelines Task for Trivy 官方 提供集成的 Azure DevOps UI,可将安全扫描直接引入工作流
GitHub Actions trivy-action 官方 Trivy 官方 GitHub Action,将 Trivy 集成进 GitHub 流水线
GitHub Actions trivy-action(社区) 社区 用 Trivy 扫描漏洞,发现漏洞时自动创建 GitHub Issue
GitHub Actions trivy-github-issues 社区 扫描 package-lock.jsongo.sum 等依赖文件,按扫描结果创建 GitHub Issue
Buildkite trivy-buildkite-plugin 社区 在项目上运行 Trivy 静态分析工具
Dagger Dagger module for Trivy 社区 提供扫描注册表镜像及 Dagger Container 对象(任意 Dagger SDK,如 Go、Python、Node.js)的函数
Semaphore Semaphore recipe 社区 在 Semaphore 工作流中扫描代码、容器、基础设施与 Kubernetes
CircleCI trivy-orb 社区 通过 Trivy Orb 为 CircleCI 工作流引入安全扫描
Woodpecker CI 原生容器步骤 社区 直接以容器步骤运行 trivy fs,用退出码决定步骤成败
Concourse CI trivy-resource 社区 扫描容器并引入流水线,支持失败管道、创建 Issue、通过对应资源向告警通道发消息
GitHub / GitLab SecObserve actions 与模板 社区 以统一的方法和参数运行多种漏洞扫描器,Trivy 集成支持扫描 Docker 镜像、本地文件系统中的漏洞以及 IaC 文件的错误配置

从清单可以看出两条路线:一是平台厂商/官方维护的 Action、Task、Orb、Plugin(如官方 trivy-action 与 Azure Pipelines Task),提供 UI 集成与开箱即用体验;二是社区围绕"扫描 + 退出码 + 报告"这一最小闭环自行封装的方案,灵活度更高。选型时建议优先官方组件,其次考虑与本仓库文档示例(如 GitLab CI 教程)模式一致的社区方案。

门禁的核心机制:exit-code 与 severity

无论接入哪个平台,Trivy 在 CI/CD 中承担"门禁"角色的关键都是 --exit-code 参数。官方文档在 Woodpecker CI 示例中的注释直接说明了这一约定:

"use any trivy command, if exit code is 0 woodpecker marks it as passed, else it assumes it failed"(使用任意 trivy 命令,退出码为 0 则 Woodpecker 判定通过,否则视为失败)

在源码中可以确认这一机制的实现。--exit-code 参数定义于 report_flags.go

ExitCodeFlag = Flag[int]{
    Name:          "exit-code",
    ConfigName:    "exit-code",
    Usage:         "specify exit code when any security issues are found",
    TelemetrySafe: true,
}

即"当发现任意安全问题时,以指定退出码退出"。退出码的最终生效逻辑在 operation.go

if opts.ExitCode != 0 && failedResults {
    return &types.ExitError{Code: opts.ExitCode}
}

可以推断,failedResults 由本次扫描中是否存在符合过滤条件(severity、include-dirty 等)的安全问题决定:一旦存在且 --exit-code 非 0,Trivy 就以用户指定的码退出,CI 平台据此把 Job 标记为失败。与之配合的还有 --exit-on-eolreport_flags.go),在操作系统到达服务/生命周期结束时以指定码退出,适合在 CI 中单独拦截 EOL 发行版的基础镜像。

双扫描门禁模式:报告与阻断分离

仓库中 GitLab CI 教程 展示了一种在多个平台通用的"双扫描"写法,值得在任意管道中复用:

script:
  # 生成报告,永不失败(exit-code 0)
  - ./trivy image --exit-code 0 --format template \
      --template "@/contrib/gitlab.tpl" \
      -o gl-container-scanning-report.json $IMAGE
  # 在控制台打印,永不失败
  - ./trivy image --exit-code 0 --severity HIGH $IMAGE
  # 仅在发现 CRITICAL 漏洞时失败
  - ./trivy image --exit-code 1 --severity CRITICAL $IMAGE

这种模式的工程含义是:第一条命令负责产出可被平台消费的报告工件(--exit-code 0 保证报告生成不受漏洞阻断),第三条命令才是真正的门禁(只对 CRITICAL 级别失败)。--severity 参数在 report_flags.go 中定义,取值为 dbTypes.SeverityNames(LOW、MEDIUM、HIGH、CRITICAL),默认输出全部级别。将"出报告"与"判成败"拆成两条命令,可以在门禁策略收紧之前先积累数据,避免流水线一开始就被历史漏洞"红屏"。

平台集成详解

Azure DevOps(官方)

Azure DevOps 是微软的云端 CI/CD 服务。Trivy 为其提供了官方 "Azure DevOps Pipelines Task",可在 Azure DevOps 的 UI 中直接配置 Trivy 扫描任务,把安全扫描低摩擦地引入流水线。相比手写步骤,官方 Task 的优势在于参数在 UI 中可视化配置、结果以 Azure DevOps 原生的测试/扫描报告形式呈现。

GitHub Actions

文档区分了三个 GitHub Actions 方案:

  1. 官方 trivy-action:Trivy 官方的 GitHub Action,用于将 Trivy 集成到 GitHub 流水线,是 GitHub 上的首选入口,支持 input 参数精细控制 Trivy 的全部选项;
  2. 社区 trivy-action:以 Trivy 扫描漏洞,一旦发现漏洞即创建 GitHub Issue,适合"漏洞即工单"的跟踪流程;
  3. 社区 trivy-github-issues:专门扫描仓库中的依赖文件(如 package-lock.jsongo.sum),再按结果创建 GitHub Issue,聚焦软件供应链依赖而非容器镜像。

仓库的 GitHub Actions 教程 补充说明:若需对传给 Trivy 的选项拥有完全控制权,可以把 Trivy 直接嵌入自定义 workflow(例如先安装二进制再执行任意 trivy image 命令),这与 GitLab 教程中的做法同构。

Buildkite(社区)

Buildkite 的 Trivy 插件提供在项目上运行 Trivy 静态分析的便捷机制,将 Trivy 封装为 Buildkite 插件参数,无需在 Build 步骤中手写完整命令。

Dagger(社区)

Dagger 是"任意位置运行的 CI/CD as code"。其 Trivy 模块提供函数,可扫描:注册表中的容器镜像,以及来自任意 Dagger SDK(Go、Python、Node.js 等)的 Dagger Container 对象。这一集成的特点是把 Trivy 变成可编程 API 的一部分——扫描逻辑可以嵌入 Dagger 定义的构建流程中,而不仅是流水线的一个步骤。

Semaphore 与 CircleCI(社区)

  • Semaphore:可在 Semaphore 工作流中使用 Trivy 扫描代码、容器、基础设施和 Kubernetes,即一次集成同时覆盖 IaC(misconfiguration)与镜像(vulnerability)两类扫描;
  • CircleCI:通过社区维护的 Trivy Orb 为 CircleCI 工作流引入安全扫描。仓库 CircleCI 教程 给出了不依赖 Orb 的原生写法,其核心步骤为:在 docker:stable-git 镜像中 checkoutsetup_remote_docker,构建镜像后用 trivy image --exit-code 0 --no-progress 执行扫描。

Woodpecker CI(社区)

Woodpecker 的集成方式最具代表性——不需要任何插件,一个标准容器步骤即可:

pipeline:
  securitycheck:
    image: aquasec/trivy:latest
    commands:
      # 使用任意 trivy 命令:退出码为 0 则 Woodpecker 判定通过,否则视为失败
      - trivy fs --exit-code 1 --skip-dirs web/ --skip-dirs docs/ --severity MEDIUM,HIGH,CRITICAL .

这条命令完整体现了前文所述的门禁机制:--exit-code 1 让发现漏洞时 Job 失败;--skip-dirs web/ --skip-dirs docs/ 跳过与依赖无关的目录。--skip-dirs 参数定义于 scan_flags.go,配置名为 scan.skip-dirs,可重复传入多个目录。文档还指出 Woodpecker 项目自身也在使用 Trivy,说明该模式经过真实管道验证。

Concourse CI(社区)

Concourse 的 trivy-resource 支持扫描容器并引入工作流,其能力超出单次扫描:可根据 Trivy 扫描输出使流水线失败、创建 Issue,以及借助 Concourse 对应的资源向告警通道(如聊天工具)发送通知。这对应了"扫描 → 阻断 → 留痕 → 告警"的完整响应链。

SecObserve GitHub Actions 与 GitLab 模板(社区)

SecObserve 提供统一运行多种漏洞扫描器的 GitHub Actions 与 GitLab 模板,用一致的方法和参数启动工具。其 Trivy 集成支持三类扫描:Docker 镜像漏洞、本地文件系统漏洞,以及 IaC 文件的错误配置扫描,适合同时使用多个扫描器、希望参数口径统一的团队。

在任意管道中落地 Trivy 的通用模式

综合官方文档与仓库教程示例,可以提炼出一个跨平台通用的接入模式,适用于 Woodpecker、GitLab、CircleCI 或任何能跑容器/命令的 CI 系统:

  1. 选择运行载体:要么直接使用 Trivy 官方镜像(aquasec/trivy:latest,如 Woodpecker 示例),要么在通用镜像中安装 Trivy 二进制(仓库提供安装脚本 contrib/install.sh);
  2. 扫描目标匹配模式trivy image <tag> 扫镜像、trivy fs . 扫代码仓库/文件系统、trivy k8s <namespace> 扫 Kubernetes,IaC 扫描由 fs 模式下的 misconfig 扫描器覆盖;
  3. 门禁策略--exit-code 0 用于仅出报告的命令,--exit-code 1 配合 --severity CRITICAL(或 MEDIUM,HIGH,CRITICAL)用于真正阻断的命令行;
  4. 报告工件:用 --format template --template 配合仓库自带模板(contrib/gitlab.tplcontrib/gitlab-codequality.tplcontrib/html.tplcontrib/junit.tplcontrib/asff.tpl)生成平台可消费的报告文件,再以平台对应的 artifacts 机制上报;GitLab 场景还可直接 include 官方模板,或在 contrib/Trivy.gitlab-ci.yml 基础上裁剪;
  5. 加速与缓存:GitLab 教程示例中通过 TRIVY_CACHE_DIR: ".trivycache/" 并缓存该目录来避免重复下载依赖数据,--no-progress(对应环境变量 TRIVY_NO_PROGRESS)则让日志在 CI 中保持干净,首次运行还可单独执行 trivy image --download-db-only 预热漏洞数据库。

小结

Trivy 的 CI/CD 生态以 --exit-code 退出码机制为轴心:官方组件(trivy-action、Azure Pipelines Task)提供平台原生的 UI 与参数化体验,社区组件(Concourse resource、Dagger 模块、SecObserve 模板等)则围绕"扫描 + 退出码 + 报告工件"这一最小闭环扩展出 Issue 创建、告警通知、多工具统一口径等能力。落地时建议遵循"报告命令永不失败、门禁命令按 severity 分级失败"的双扫描模式,并复用仓库教程(GitLab CICircleCI)中已验证的配置骨架与 contrib 下的报告模板,即可在任何主流 CI 平台上建立起稳定、可审计的 DevSecOps 扫描门禁。

登录后查看全文
热门项目推荐
相关项目推荐