trivy-action 实测:把 Trivy 扫描塞进 GitHub Actions 的正确姿势
项目速览:将 Trivy 作为 GitHub 操作运行以扫描 Docker 容器映像是否存在漏洞。
秒懂
- 它是什么?
- trivy-action 是 Aqua Security 官方提供的 GitHub Action,用于在 CI 中直接调用 Trivy 扫描容器镜像、文件系统或 IaC 配置。它封装了安装、缓存和扫描流程,但配置顺序和缓存策略有讲究。
- 适合谁用?
- trivy-action 适合已经在 GitHub Actions 中构建镜像或管理 IaC 的团队,尤其是希望用最少配置获得 Trivy 扫描能力的用户。它不适合需要精细控制 Trivy 版本或扫描缓存的项目,也不适合扫描逻辑复杂、依赖自定义脚本的场景。
- 能商用吗?
- 可以。Apache-2.0 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
- 还在维护吗?
- 在维护。仓库最近一次提交在 27 天前。
- 用什么语言写的?
- 主要是 Shell(依据 GitHub 的语言统计)。
以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。
开源项目深度解析
它解决什么问题:把 Trivy 的安装和调用从 CI 里抽出来
Trivy 本身是一个命令行工具,扫描镜像、文件系统或 IaC 配置。但在 GitHub Actions 里直接用,你得先写步骤安装 Trivy、处理版本、下载漏洞数据库、再写扫描命令。trivy-action 把这些都封装成一个 action,你只需要在 workflow 里指定扫描类型和扫描目标。它面向的是已经在用 GitHub Actions 做 CI 的团队,尤其是那些不想维护 Trivy 安装逻辑的人。README 里的第一个例子就是典型的镜像扫描:先 docker build,然后调用 trivy-action 扫描刚构建的镜像。这个 action 由 Aqua Security 官方维护,属于 Trivy 生态的官方配套,不是第三方封装。
机制拆解:它其实是个包装器,真正的逻辑在 Trivy 里
从 README 能看出,trivy-action 不是一个独立的扫描器。它默认第一步调用 aquasecurity/setup-trivy 来安装指定版本的 Trivy,然后执行扫描命令。这意味着 action 的行为完全取决于 Trivy 本身的能力。扫描类型由 scan-type 输入决定,可选 image、fs、repo 等。scan-ref 或 image-ref 指定扫描目标。format 控制输出格式,exit-code 决定扫描到漏洞时是否让 CI 失败。这些输入最终都会映射成 Trivy 的命令行参数。值得注意的是,README 明确说,如果提供了 trivy-config 文件,那么大部分选项都可以写在 trivy.yaml 里,action 的输入仅用于向后兼容。但 scan-ref、image-ref 和 scan-type 这三个必须在 action 里指定,不能放配置文件。这说明 action 的设计意图是让配置文件成为主要选项来源,action 输入只是兜底。
配置顺序:Viper 的优先级可能和你想的不一样
README 里专门有一节讲选项优先级,顺序是:GitHub Action flag 最高,然后是环境变量,再是配置文件,最后是默认值。这个顺序很重要。比如你在 trivy.yaml 里设置了 severity: CRITICAL,但 action 里没有传 severity 输入,那么环境变量 TRIVY_SEVERITY 会覆盖配置文件。如果你同时设置了 action 输入和配置文件,action 输入会赢。这个机制容易踩坑:很多人习惯把配置都放 trivy.yaml,却忘了 action 的输入可能默默覆盖了它。比如 action 默认的 format 可能是 table,如果你在配置文件里写了 format: json,但 action 里没显式设置 format,那么配置文件生效。但如果你在 action 里写了 format: 'table',配置文件就失效了。所以要么全部用配置文件,要么全部用 action 输入,混用时要清楚优先级。
跑起来:最小配置到完整示例
最简单的用法是扫描镜像。在 workflow 里构建镜像后,加一步:uses: aquasecurity/trivy-action@v0.36.0,with 里写 image-ref 指向镜像,format 设为 table,exit-code 设为 1,这样有漏洞时 CI 会失败。这是 README 的第一个例子。如果你要扫描文件系统,改用 scan-type: 'fs',scan-ref: '.',并指定 trivy-config: trivy.yaml。trivy.yaml 里可以写 format: json、exit-code: 1、severity: CRITICAL 等。注意,配置文件里不能写 scan-ref 和 scan-type。缓存默认开启,action 会把漏洞数据库、Java DB 和 checks bundle 缓存在 $GITHUB_WORKSPACE/.cache/trivy 目录。要关闭缓存,设 cache: 'false'。如果你已经用 setup-trivy 手动安装了 Trivy,可以设 skip-setup-trivy: true 跳过自动安装。仓库里还有扫描 tarball、Git 仓库、rootfs、IaC、SBOM、私有 registry 的示例,但 README 被截断了,具体细节无法确认。
缓存:默认开启,但跨分支有坑
缓存是 trivy-action 的一个亮点,但也可能是麻烦。它用 actions/cache 做底层,但不需要你手动配置 key,自动恢复和保存。默认缓存目录是 $GITHUB_WORKSPACE/.cache/trivy。问题在于 GitHub Actions 的缓存访问限制:一个 workflow 只能访问当前分支或默认分支创建的缓存。这意味着如果你在 feature 分支跑扫描,它可能无法恢复 main 分支的缓存,导致每次都要重新下载漏洞库。README 建议用 cron job 在默认分支定期更新缓存,然后在扫描 workflow 里设置 TRIVY_SKIP_DB_UPDATE=true 和 TRIVY_SKIP_JAVA_DB_UPDATE=true 来跳过下载。这个方案可行,但增加了维护成本。如果你不想维护缓存更新 workflow,又担心 rate limiting,可以关掉缓存。但 README 明确说建议保持开启,因为不缓存容易触发下载频率限制。
局限性:它不适合所有扫描场景
trivy-action 的封装带来了便利,也带来了限制。首先,它依赖 GitHub Actions 环境,意味着你无法在本地或非 GitHub 的 CI 中复用它。其次,扫描类型虽然多,但每个类型都需要单独的 action 调用,如果你要在一个 workflow 里同时扫描镜像和 IaC,得写两个步骤,每个步骤都要指定 scan-type。这并不复杂,但比直接写 trivy 命令多了一层间接性。更关键的是,如果你需要自定义 Trivy 的扫描参数,比如自定义模板、指定多个 severity、或者使用 Trivy 的插件机制,action 的输入可能不够用。README 提到了可以用 trivy-config 文件,但配置文件的选项范围受 Trivy 版本限制。另外,action 默认安装的 Trivy 版本由 version 输入控制,默认值在 README 截断部分看不到,但如果你需要特定版本的 Trivy,必须显式指定,否则可能用了过旧或过新的版本。
替代方案:直接调用 setup-trivy 加 trivy 命令
trivy-action 不是唯一选择。README 本身就展示了另一种方式:先手动调用 aquasecurity/setup-trivy@v0.2.0,设置 cache: true 和 version: v0.74.0,然后再运行 trivy 命令。这种方式更透明,你完全控制 Trivy 的安装和调用,可以自由组合参数,比如用 --template 指定输出模板,或者用 --severity 覆盖多个级别。区别在于,trivy-action 把安装和扫描封装成一个步骤,而手动方式需要两个步骤,但换来的是灵活性。如果你要扫描多个目标,或者需要复杂的后处理,手动方式更合适。而且 setup-trivy 本身也支持缓存,所以缓存优势并不只在 trivy-action 里有。另外,你可以直接用 Trivy 官方提供的 Docker 镜像在 CI 里跑扫描,但那需要你自己管理容器运行,更麻烦。所以替代方案的核心差异是:trivy-action 牺牲了控制权换取了简洁,手动方式反过来。
维护与许可:Apache-2.0 下的官方组件
trivy-action 的许可证是 Apache-2.0,这意味着你可以自由使用、修改和分发,只要保留版权声明。它由 Aqua Security 维护,和 Trivy 主项目保持同步更新,最近一次发布是 v0.36.0,日期是 2026 年 4 月。版本更新频繁,说明项目活跃,但也意味着你要留意版本变化,因为 action 的行为可能随 Trivy 版本升级而改变。升级成本主要在配置兼容性:如果 Trivy 的 CLI 参数发生变化,action 的输入可能也需要调整。另外,action 默认依赖 setup-trivy,这增加了依赖链,但 setup-trivy 也是官方维护的。在采用前,你应该检查当前使用的 trivy-action 版本对应的 Trivy 版本,确保它支持你需要的扫描功能。由于 README 截断,无法确认所有输入和默认值,实际使用时应参考最新文档。
编辑结论
trivy-action 适合已经在 GitHub Actions 中构建镜像或管理 IaC 的团队,尤其是希望用最少配置获得 Trivy 扫描能力的用户。它不适合需要精细控制 Trivy 版本或扫描缓存的项目,也不适合扫描逻辑复杂、依赖自定义脚本的场景。采用前应验证三点:确认你使用的 trivy-action 版本对应的 Trivy 版本是否满足扫描需求;检查 trivy.yaml 中定义的选项是否与 action 的输入冲突,尤其是 scan-ref 和 image-ref 不能同时设置;测试缓存更新策略,避免因 GitHub 分支缓存限制导致每次扫描都重新下载漏洞库。如果你只需要一次简单的镜像扫描,trivy-action 的默认配置足够;但如果你要维护多仓库、多扫描类型的流水线,建议直接调用 setup-trivy 加 trivy 命令,把控制权握在自己手里。
社区笔记