写过代码的都以为给仓库提了 PR 就能跑 CI,今天 GitHub 把这件事从根上截了
写过代码的都以为给仓库提了 PR 就能跑 CI,今天 GitHub 把这件事从根上截了。
——但这次不是帮你检测恶意 workflow,是直接告诉你:谁能触发 workflow、什么事件能触发 workflow,以后不是你 YAML 说了算,是管理员定的规则说了算。
2026 年 6 月 18 日,GitHub 正式公开预览了 Workflow Execution Protections。这是 GitHub Actions 设置里一个全新的「Policies」分区,基于 GitHub Rulesets 框架,把 workflow 触发的控制力从仓库维护者手里,转移到了组织层面的管理员手里。
问题:workflow 触发这件事,从来没被管住过
以前的逻辑很简单:谁有仓库写权限,谁就能推代码,谁推了代码,谁就能触发 workflow。
这个逻辑有两个明显的漏洞。
第一个漏洞:权限混淆。 你给一个 contributor 开了 Write access,是因为他需要提交代码。但 Write access 同时意味着他可以在同一个 commit 里改 workflow 文件,让 workflow 去做任何事——拉取密钥、上传产物到第三方服务、把 runner 当跳板。CI 的权限,本来是给自动化用的,现在变成了给恶意代码开了后门。
第二个漏洞:事件无法控制。 pull_request_target、workflow_dispatch 这些事件,谁想触发就能触发。一个钓鱼 PR 可以在描述里诱导 maintainer 合并,从而触发 pull_request_target——这个事件天然在目标分支的上下文中运行,权限比普通 PR 高得多。
过去的解法是靠最佳实践:最小权限 token,保护分支、环境限制。但这些都是事后补丁,没有一个在 workflow 运行之前就把「不该触发的情况」拦住。
Workflow Execution Protections:从文件级控制到规则级控制
Workflow Execution Protections 的思路完全不同——它在 workflow 文件执行之前,套了一层组织级别的白名单。
这套保护基于 GitHub Rulesets 框架,有两种规则类型:
Actor 规则: 控制谁能触发 workflow,支持细粒度到个人用户、仓库角色(Read/Maintain/Admin)、GitHub Apps、Copilot、Dependabot。这意味着你可以给一个 contributor 开 Write access 让他提交代码,同时禁止他触发 workflow——写代码和跑 CI,不再是同一件事。
Event 规则: 控制哪些事件能触发 workflow,比如禁止 pull_request_target、限制 workflow_dispatch 只能由 Maintainer 触发。
Rulesets 本身支持企业级、组织级、仓库级三级作用域,可以通过仓库自定义属性(custom properties)批量应用到特定类型的仓库上,而不是一个一个仓库去改 YAML。
此外还支持 Evaluate 模式:规则先以影子模式运行,把会拦截哪些触发记录下来,管理员确认没问题再开启强制执行。这解决了「怕开规则把现有 workflow 搞挂」的顾虑。
三个真实攻击场景被直接点名
GitHub 官方博客明确点名了三件事 Workflow Execution Protections 能截住:
毒化流水线执行(Poisoned Pipeline Execution)。 pull_request_target 在公网仓库里被频繁滥用——攻击者发一个 PR,里面包含一个被篡改的 workflow 文件,等 maintainer 合并后自动执行。Event 规则可以直接把 pull_request_target 列为禁止事件,从根上断掉这条路。
手动触发滥用。 workflow_dispatch 让任何有写权限的人都能手动启动一个 workflow。限制为仅 Maintainer 可触发,可以防止低权限账户乱点。
不受信任身份的执行。 直接把低信任身份(新的 bot 账号、未验证的外部 contributor)从 workflow 触发资格里踢出去,而不剥夺他们的代码提交权限。
配置入口:别去 General 设置里找
值得注意的是,Workflow Execution Protections 的配置入口不在 GitHub Actions 的「General」设置里,而是在一个全新的「Policies」子分区。这意味着它和传统的 Actions 设置是分开的,管理员需要知道去哪儿找。
Organizations → Settings → Actions → Policies → New ruleset
每个 ruleset 可以包含 Event 规则和 Actor 规则,每个规则可以设置为 Allow 或 Prohibit,作用于匹配的触发事件或触发者。
和已有的安全层是什么关系
Workflow Execution Protections 不是替代品,而是新增了一层。
它和现有的以下机制是叠加关系:
| 机制 | 层级 | 功能 |
|---|---|---|
| 最小权限 Token Scope | 运行时 | 限制凭证能访问哪些资源 |
| Protected Environments | 部署层 | 哪些环境需要审批 |
| 环境变量 Secrets | 配置层 | 密钥不暴露给未授权 job |
| Workflow Execution Protections | 触发层 | 谁/什么能触发 workflow |
| 自动恶意 workflow 审批门控 | 检测层 | GitHub 自动发现可疑 workflow 并暂停 |
这五层一起用,才能说一个仓库的 CI 安全是完整的。
现在能怎么落地
如果你管着一个组织的 GitHub Actions 安全策略,现在可以做三件事:
第一步:去 Policies 分区建一个 Evaluate 模式的 ruleset。 把 pull_request_target 设为 Prohibit,把外部账号设为 Actor Prohibit,跑两周看有多少触发会被拦,记录下来再决定是否开启强制。
第二步:把 Actor 规则当成权限分离工具用。 很多仓库给所有人开了 Write access 但实际上只需要他们提交代码,Actor 规则可以在这里做一次精细化分离。
第三步:把 Evaluate 模式的结果同步给安全团队。 Rulesets 的日志可以导出,这些数据本身就是一次完整的工作流触发审计。
一句话总结:GitHub 把「谁能跑 workflow、什么条件下能跑」这件事,从 YAML 文件手里收走,放到了组织策略里。 这不是某个功能的补充,是权限模型在 CI/CD 这一层的重新设计。
评论区
登录后可评论。