加载失败
这篇讨论围绕 GitHub Actions(GitHub 提供的 CI/CD 自动化系统)里 action 依赖到底该用 tag 还是 commit SHA 固定。评论把焦点放在供应链安全:第三方 action、composite action(会继续调用其他 action 的复合 action)、NPM 依赖和云端凭证都会让工作流在执行时暴露出更大的攻击面。有人提到 GitHub 正在推进 Immutable Releases(不可变发布)来减少 tag 被改写的问题,也有人借助 Renovate、Dependabot、zizmor 等工具做自动更新和审计。讨论还延伸到 self-hosted runner、Buildkite、Dagger(一个可编程的 CI 运行时)和 Forgejo(一个开源 Git 服务平台),说明大家不只是想修补一个漏洞,而是在重新思考 CI 的信任模型。
不少评论认为,`uses:` 里继续用 tag 或 major version tag 太危险,至少第三方 action 应该直接固定到 commit SHA。原因是 tag 随时可能被重定向,甚至出现 `v5.2.3` 之类的“正常更新”外衣下的投毒版本。大家还提醒,光锁顶层 action 不够,composite action 里还可能继续引用其他可变目标,NPM 依赖和远程下载也会把风险继续向外扩散。有人补充说,SHA collision 在 Git/GitHub 场景下几乎没有现实可利用性,但组织级 whitelist 也不是绝对保险,安全供应商自己都可能出问题。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9]
另一条讨论线聚焦在“锁死以后怎么维护”。Renovate、ratchet、pinact 被提到可以自动把 action 从 tag 改成 SHA,并在后续更新时继续同步哈希和注释,减少人工处理。问题在于,SHA pinning 会让 GitHub 自带的 vulnerability alerts 变得不完整,团队只能借助 zizmor 这类外部工具补回漏洞信息。评论还指出,如果把这些更新 PR 全自动合并,就等于放弃了真正的人工审查;但如果不自动化,维护成本和集中治理压力又会迅速上升。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9] [来源10]
有人认为真正的风险不只是版本是否固定,而是工作流本身能否在运行时接触到不该碰的秘密。`pull_request_target` 被直接批评为危险触发器,因为它可能让未验证的 PR 代码拿到仓库 secrets;而 OIDC federation(runner 与云资源的身份联邦)则会把云端临时凭证提前发出去,后续即使 action 变了,这些权限也已经存在。评论还说,静态解析 YAML 不足以看穿深层 composite action 树和 runtime template injection,因此更需要运行时检测。像 hasp、zizmor 这类工具被当作补丁:前者通过 sandbox、token broker、landlock、seccomp 和 eBPF 把 runner 当成潜在恶意环境来处理,后者则尽量补足审计能力。
不少人把矛头指向 GitHub Actions 的编程体验本身,认为 YAML 只是表象,真正糟糕的是大量 action 本质上像 `curl | bash`。评论里有人想要的是一种更像脚本语言、带可观测性和本地 mock 环境的混合式 CI 运行时,而不是一堆隐藏行为的配置拼图。也有人拿 Jenkins 来对比,说它的 Groovy/DSL 语言和报错同样糟糕,但至少直接写 shell 脚本更容易理解。另一些人指出,现代 GHA 已经复杂到很难本地模拟,开发者常常要花很多时间“盲飞”排查,而 `act` 只能部分缓解这个问题。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9]
还有一批评论把问题上升到平台选择:GitHub Actions 之所以还能用,很多时候只是因为它最省事,尤其适合 Windows、macOS、Linux 三平台一起跑的项目。可一旦考虑到黑箱、卡顿、宕机和难以排查的问题,大家就开始看向自托管 runner、Spot instance、WarpBuild、runs-on、Buildkite、RWX 之类的替代方案。Dagger(一个可编程的 CI 运行时)也被拿来举例,强调它想把 CI 从“绑定 GitHub 事件”里拆出来,让流水线运行层和 git 触发层解耦。即便如此,很多人仍承认 GitHub 的 UI 和 `gh` CLI 体验很好,真正难的是找到一个能同时替代代码托管、PR 流程和 CI 的完整方案。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9] [来源10] [来源11] [来源12] [来源13]
SHA pinning: 把 action 依赖固定到某个 commit hash,避免 tag 被改写或指向恶意版本。
composite action: 由多个 step 或其他 action 组合而成的 action,可能继续引用更多外部依赖。
lockfile: 记录精确依赖版本的文件;GitHub Actions 原生并没有完整的 lockfile 机制。
Immutable Releases: GitHub 计划中的不可变发布机制,目标是让已发布内容无法被悄悄替换。
Renovate: 自动创建依赖升级 PR 的机器人,可把 GitHub Actions 的 tag 更新为 SHA。
Dependabot: GitHub 的自动依赖更新与漏洞提醒工具。
zizmor: 针对 GitHub Actions 的安全审计工具,用来补足静态检查和漏洞信息。
pull_request_target: GitHub Actions 的一种触发器,容易在 PR 场景下把高权限 secrets 暴露给未验证代码。
OIDC federation: runner 与云厂商通过 OIDC 交换临时身份凭证的机制,若流程失守会放大权限泄露。