供应链防线深度实践:GitHub Actions 的执行前拦截来了,Agent CI/CD 还要补哪三道门
调研日期:2026-07-30
本文目标:把 GitHub Actions 新增的可疑工作流执行前审批,转成 Agent 参与提交、修改和发布时可执行的供应链防线。
2026-07-28,GitHub 宣布:在 github.com 的公共仓库中,某些被识别为潜在恶意的 GitHub Actions 工作流会在启动前被挂起,必须由具写权限的协作者在已认证的 Web 会话中审核并批准后才会继续执行。该保护由 GitHub 自动应用,不需要仓库额外配置;公告同时明确,它目前不覆盖 GitHub Enterprise Server。
这是一条很重要的防线,但它不是“打开自动化后就安全”的许可证。特别是当 Agent 能提交 PR、修改.github/workflows/*.yml、调用发布工具时,安全边界应该从“事后看到告警”前移到“执行前能否获得能力”。
一、先把公告能力和团队责任分开
问题 | GitHub 本次已提供的能力 | 团队仍必须做的事 |
可疑工作流是否启动 | 某些被识别为潜在恶意的工作流会被挂起,等待写权限协作者批准 | 把工作流文件的变更视作高风险代码审查对象 |
是否需要开启 | 公告称公共 github.com 仓库无需额外配置 | 私有仓库、GitHub Enterprise Server 与自托管运行器仍要自行设计策略 |
凭据保护 | 执行前多了一道人工门 | 默认最小化 |
误报与漏报 | 平台决定哪些运行被判定为可疑 | 用允许列表、策略检查和发布环境审批兜住平台检测覆盖不到的路径 |
工程推断:这次变化说明 CI/CD 的防御重点正在从“扫描出风险后通知人”向“在工作流真正拿到 Token、Runner 和网络访问前阻断”移动。对 Agent 而言,这是更符合现实的门槛:模型可以提出变更,但不能自动获得执行能力。
二、Agent 参与 CI/CD 后,威胁面多了一层“工作流即代码”
传统代码审查主要看业务逻辑;Agent 场景还要把下面这些变化单独标红:
Agent 生成 PR ├─ 改应用代码 → 常规测试、代码审查 ├─ 改依赖与 Action 引用 → 供应链校验、版本 / SHA 固定 └─ 改 .github/workflows/*.yml → 触发方式、权限、密钥、Runner、部署边界的专项审查最危险的不是一行显眼的rm -rf,而是看似正常的能力组合:把触发器改为pull_request_target、给工作流加入id-token: write、在不可信 PR 中 checkout 贡献者代码,或让自托管 Runner 执行外部输入。它们单独看可能各有合理场景,拼起来却能让不可信代码接触基础仓库 Token、组织机密或云角色。
所以,Agent 提交工作流变更的合理默认值应是:测试可以自动运行,权限升级和部署必须分离并等待人确认。
三、四道门:把“能提 PR”与“能影响生产”拆开
Agent / 开发者提交 PR │ ├─ 门 1:分支保护 + 工作流文件 CODEOWNERS 审查 ├─ 门 2:无密钥、最小权限的 PR 静态策略检查 ├─ 门 3:平台对可疑 workflow 的执行前审批(公共 github.com) └─ 门 4:发布环境审批 + 短期 OIDC 云身份 │ ▼ 受控生产变更这里的关键不是堆很多扫描器,而是让每一道门都减少一种能力:
- 审查门:只有指定维护者可批准工作流路径的变更。
- 策略门:PR 检查不读 Secrets、不申请 OIDC,只识别高风险差异并要求人工复核。
- 执行门:让 GitHub 的自动挂起成为公共仓库的额外刹车,而不是唯一刹车。
- 部署门:生产权限只存在于批准后的部署 Job;不把长期云密钥放回 PR 工作流。
四、可运行示例:对工作流变更做“无密钥”的专项检查
把下面文件保存为.github/workflows/guard-workflow-changes.yml。它只在修改工作流文件的 PR 上运行,默认只读仓库内容,不读取 Secrets,也不申请 OIDC。示例使用actions/checkout@v7以保持可运行;生产仓库应按组织策略将第三方 Action 固定到已审核的完整 commit SHA。
name: guard-workflow-changes on: pull_request: paths: - ".github/workflows/**" permissions: contents: read jobs: review-workflow-diff: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 with: fetch-depth: 0 - name: Flag high-risk workflow additions env: BASE_REF: ${{ github.base_ref }} run: | set -euo pipefail git fetch --no-tags origin "$BASE_REF" --depth=1 diff="$(git diff --unified=0 "origin/$BASE_REF"...HEAD -- .github/workflows || true)" printf '%s\n' "$diff" # 这是升级审查门,不是完整的 YAML 安全分析器。 # 命中后让维护者审查,而不是让 PR 自动获得高权限。 if printf '%s\n' "$diff" | grep -E '^\+.*(pull_request_target|write-all|id-token:[[:space:]]*write|ACTIONS_ID_TOKEN_REQUEST_(URL|TOKEN)|secrets\.)'; then echo "High-risk workflow change detected; maintainer review is required." exit 1 fi验证方式很直接:在一个测试分支新增普通的pull_request工作流,检查应通过;再新增pull_request_target或id-token: write,检查应失败。失败的含义是“需要专项审查”,不是这些配置永远不能使用。
如果确实有发布 Job,再把它放进另一条只由受信事件触发的工作流,例如workflow_dispatch、受保护的 tag 或发布事件,并把权限收在 Job 级:
permissions: contents: read jobs: deploy: if: github.ref_protected == true environment: production permissions: contents: read id-token: write # 只允许该部署 Job 向云提供方换取短期身份 runs-on: ubuntu-latest steps: - run: echo "Authenticate with OIDC after the production environment is approved"id-token: write只允许 Job 请求 OIDC JWT,本身不等于获得某个云资源的写权限;真正的权限来自云侧对 issuer、repository、ref、environment 等声明的信任策略。因此,云侧也必须把信任条件限制到受保护分支和指定环境。五、把平台保护接进组织策略,而不是取代组织策略
至少完成下面五件事:
- 将仓库或组织的默认
GITHUB_TOKEN权限设为只读;需要写入时在具体 Job 显式声明最小 scope。 - 仅允许经过审核的 Action / 可复用工作流;在能使用的范围内强制完整 SHA 固定,避免 tag 被重指向。
- 对
.github/workflows/**配置 CODEOWNERS 与分支保护,Agent 生成的这类 diff 不能由 Agent 自行批准。 - 使用 GitHub Actions 的执行保护策略限制触发者与事件;特别评估是否应限制或禁止
pull_request_target。 - 不让不可信 PR 使用自托管 Runner、生产环境或部署用 OIDC;这些能力只在受保护 ref 的发布 Job 中开放。
对于大型组织,还应把“谁可以触发工作流”与“谁可以推送代码”区分开。GitHub 的 workflow execution protections 可以按 actor 和 event 做限制,这能阻止“有写权限但不应执行 CI”的角色直接启动高权限流程。
六、不要踩这四个坑
1)看到“需批准”就直接点通过
审批应检查触发器、permissions、Secret 使用、Action 版本、Runner 类型和外联命令。它是一项变更审查,不是积压任务的清除按钮。
2)在pull_request_target中 checkout PR 代码
官方文档指出,此事件以基础仓库的高信任上下文运行,可能访问基础仓库 Token 与机密。除非你能明确证明不执行不可信代码,否则用普通pull_request做测试,部署移到独立工作流。
3)把id-token: write放在工作流根部
这样所有 Job 都能申请 OIDC JWT。应把它只赋给真正需要云身份、且受环境审批保护的部署 Job。
4)用长期云 Secret 解决“审批后登录太麻烦”
长期 Secret 一旦暴露,审批只能保护“本次运行”,保护不了凭据生命周期。优先让 OIDC 按 Job 换取短期、带条件的访问令牌。
结语
GitHub 对可疑工作流增加的执行前审批,是供应链安全向“能力尚未发放时就拦住”迈进的一步。对 Agent 工程来说,最该吸收的不是按钮本身,而是这一条原则:生成变更的能力可以广泛,执行敏感动作的能力必须稀缺、短期、可审计。
先用本文的无密钥 PR 检查为工作流 diff 加一道门,再把部署权限收回到受保护环境和短期 OIDC。这样即使 Agent 写出了看似合理的 YAML,它也无法单靠一次提交获得生产执行权。
来源与延伸阅读
- GitHub Actions holds potentially malicious workflows for approval:GitHub 官方公告,发布于 2026-07-28。
- GitHub Actions Security reference:官方安全参考,涵盖
pull_request_target、OIDC 与 Secrets 风险。 - Workflow execution protections:官方工作流执行策略说明。
