Trivy CI/CD 集成全景:用官方与社区管道工具构建 DevSecOps 扫描门禁
本篇技术指南基于 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.json、go.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-eol(report_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 方案:
- 官方 trivy-action:Trivy 官方的 GitHub Action,用于将 Trivy 集成到 GitHub 流水线,是 GitHub 上的首选入口,支持
input参数精细控制 Trivy 的全部选项; - 社区 trivy-action:以 Trivy 扫描漏洞,一旦发现漏洞即创建 GitHub Issue,适合"漏洞即工单"的跟踪流程;
- 社区 trivy-github-issues:专门扫描仓库中的依赖文件(如
package-lock.json、go.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镜像中checkout并setup_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 系统:
- 选择运行载体:要么直接使用 Trivy 官方镜像(
aquasec/trivy:latest,如 Woodpecker 示例),要么在通用镜像中安装 Trivy 二进制(仓库提供安装脚本 contrib/install.sh); - 扫描目标匹配模式:
trivy image <tag>扫镜像、trivy fs .扫代码仓库/文件系统、trivy k8s <namespace>扫 Kubernetes,IaC 扫描由fs模式下的 misconfig 扫描器覆盖; - 门禁策略:
--exit-code 0用于仅出报告的命令,--exit-code 1配合--severity CRITICAL(或MEDIUM,HIGH,CRITICAL)用于真正阻断的命令行; - 报告工件:用
--format template --template配合仓库自带模板(contrib/gitlab.tpl、contrib/gitlab-codequality.tpl、contrib/html.tpl、contrib/junit.tpl、contrib/asff.tpl)生成平台可消费的报告文件,再以平台对应的 artifacts 机制上报;GitLab 场景还可直接 include 官方模板,或在 contrib/Trivy.gitlab-ci.yml 基础上裁剪; - 加速与缓存: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 CI、CircleCI)中已验证的配置骨架与 contrib 下的报告模板,即可在任何主流 CI 平台上建立起稳定、可审计的 DevSecOps 扫描门禁。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00