审查本地 Actions 权限策略与任务依赖
从单份本地 YAML 快照核对明确的策略来源、省略权限、精确依赖与完整只读 job 声明。
从能确认来源的单份工作流开始
Viper 维护者反馈三个工作流中的六个 job 缺少明确权限声明。T303 每次审查一份复制的工作流。选择自己检出的 UTF8 YAML,无需仓库凭据、令牌或网络访问。其他工作流分别审查,并保留每份文件的哈希与报告。
报告保留 workflow 层声明和每个 job 的完整原映射,包括 steps、run、条件和矩阵。这些都是解析后的数据;Shell 命令、HTML 字符串、本地动作路径和远程 uses 不会运行或抓取。结果是审查记录,不是可以直接提交的修改版工作流。
| 模式 | 审查行为 | 证据状态 |
|---|---|---|
| unknown | 缺少 workflow/job 权限时保持未知 | 不猜仓库设置 |
| read-all / write-all | 保留所选字面模式 | 用户上下文仍未验证 |
| mapping | 解析唯一键 JSON,省略权限设为 none | 明确用户上下文,不做实时查询 |
修改文件前先看被选中的策略
job 声明优先于 workflow 声明和用户默认上下文。明确的映射会把所有省略的支持权限设为 none;空映射让全部权限为 none。因此 job 映射会替换 workflow 映射,不会把 workflow 中已授予而 job 中省略的项合并回来。
已核验六 job 示例中,workflow 的 contents: read 与 issues: write 适用于 build。deploy 明确要求 id-token: write,所以 contents 和 issues 为 none。empty 明确声明 {},所有权限都为 none。策略来源列区分 job、workflow、provided-default 与 unknown-default。
- 支持权限键固定于 2026-10-07 配置;未知未来键会失败,不会悄悄消失。
- id-token 支持 write/none,vulnerability-alerts 支持 read/none;非法访问值让整份审查失败。
- read-all/write-all 保留字面模式,scopes=null;不展开为虚构的实际逐项授权。
- 只在 mapping 模式解析默认 JSON,4KiB UTF8 预算在所有模式生效。明确选择了非法上下文,即使 workflow 策略优先也会失败。
区分实际依赖边与未解析声明
每个 job 记录保留全部 needs 声明。只有精确存在的字面 job ID 才形成依赖边;缺失目标和表达式分别记录问题。条件、矩阵声明和 job/step uses 保留原文字与位置,实际运行行为仍未知。
示例有七条 needs 和五条已有边。cycleA 与 cycleB 构成一个精确强连通组;下游 after 不属于环,它的缺失目标与表达式是两个独立问题。自引用形成单 job 环。这是声明关系图,不模拟哪些 job 实际执行。
| 状态 | 含义 |
|---|---|
| permissionUnknown=true | 未选中 job/workflow 声明或用户提供默认值 |
| incomplete=true | 未知策略、缺失/表达式依赖、uses、条件、矩阵或环需要进一步上下文 |
| runtimeAccessVerified=false | 即使声明完整,也未测试实时令牌权限 |
| runtimeRestrictionsUnknown=true | 仓库、fork、Dependabot 与可复用工作流限制未核验 |
下载完整审查并恢复
表格最多显示 200 个 job,每格最多 2,000 个 UTF16 字符。摘要解释数量;完整 JSON 与 CSV 保留每个 job、原声明、uses 引用和依赖。JSON 另含全部关系边、精确环、问题、默认值来源和源文件 SHA256。简短表格不代表导出缺少记录。
本地原生测试在一份真实输入中交付 1,000 个 job、10,000 条精确边与 10,000 个 uses,由独立 PyYAML 读取器和可达关系算法检查全部行。另一份输入恰好达到两份下载合计 10MiB,增加一个源字节即超限。实际原生进度取消会丢弃结果,同一支持输入随后恢复;浏览器交互验收由主控另行维护。
- 单输入 5MiB、解析后值节点 100,000 个、深度 64、job 1,000 个、needs 与 uses 各 10,000 个;默认 JSON 4KiB;两份下载合计 10MiB。全部限制同时生效。
- 只支持 YAML1.2 core、唯一字符串键与普通有限安全数字/字符串/布尔/null/映射/数组。YAML1.1、多文档、自定义/Set/二进制/日期标签、不安全整数、重复键与循环别名整体失败。
- 无环别名使用 yaml2.9.1 加权展开保护值 50,不承诺 50 次字面引用。已测单标量锚点接受 49 次引用、拒绝下一次。
- 失败后修正不支持结构或真实超限项重跑;取消后没有部分成功工件。原文件始终不被编辑。
- 完整模式有效性、依赖漏洞、授权必要性、实时令牌权限和自动仓库修复均不属于本审查。
参考资料
- 维护者任务:六个 job 缺少明确权限
2026-10-07 阅读原问题正文,涉及三个工作流。本工具逐份审查已提供快照,不复述作者的实时安全结论。
- GitHub 工作流权限与 needs 语法
2026-10-07 阅读官方权限表、省略项 none、优先级和 needs 章节;实际运行限制超出本地快照范围。
- yaml 解析转换与别名保护
2026-10-07 阅读官方解析/Map/alias 选项,生产锁定 ISC yaml2.9.1,拒绝不支持集合与指令。
本分类工具使用说明
展开工具,查看操作步骤、可调选项和支持范围,再直接进入工作区。
GitHub Actions 权限与任务依赖审查审查单份本地 workflow 声明的令牌权限、实际 needs 边、环与动作引用,导出完整 JSON 和 CSV。
选择一份 UTF8 YAML1.2 工作流快照。根据 workflow 声明或明确提供但未经验证的仓库默认值,解析 job 的权限映射。缺省值保持未知,全局模式保留原声明;只审查依赖和 uses,不运行表达式、不联系 GitHub。
操作步骤
- 从自己的仓库复制并选择一份 workflow YAML。
- 默认保留未知;只有明确掌握仓库设置时才提供上下文,选择 JSON 映射后才解析文本框。
- 检查权限来源、省略项 none、缺失或未解析的依赖,以及精确环成员。
- 下载完整 JSON/CSV 与每个 job 的原声明;仓库设置和实际运行权限需另行核验。
可调选项
- 仓库默认权限上下文
- 未知 · 声明 read-all 上下文 · 声明 write-all 上下文 · 明确 JSON 映射
仅为用户明确提供的上下文,不查询仓库、不做实时验证。
- 明确的默认权限 JSON
- {}
只在选择 JSON 映射时解析;4KiB 文本预算始终生效。映射省略项为 none。
能力与限制
- 单文件最多 5MiB;解析后 YAML 值节点 100,000 个、深度 64、job 1,000 个、needs 声明和 uses 各 10,000 个。默认权限 JSON 最多 4KiB;完整 JSON/CSV 合计 10MiB。各项限制同时生效。只预览前 200 个 job,每格最多 2,000 个 UTF16 字符;下载保留全部记录。
- 只支持单份 YAML1.2 core 文档、唯一字符串映射键、普通映射/数组/标量和无环别名。yaml2.9.1 的加权别名展开保护值为 50,不承诺支持 50 次字面引用。自定义/Set/二进制/日期标签、YAML1.1、环、重复键、非有限数、不安全整数和未知权限键会让整份审查失败。
- 权限键固定于 2026-10-07 配置。job 映射替换 workflow 映射;省略的权限为 none,{} 表示全部 none。缺少默认值仍未知,用户提供的默认值仍未验证。read-all/write-all 保留字面模式,不虚构逐项实际权限。
- 只读单份已提供快照,不是完整 workflow 模式验证、安全结论或实时令牌测试。fork、Dependabot、可复用工作流和仓库限制仍未知。矩阵、条件、needs 表达式与 job/step uses 只保留原文;不抓取动作、不改仓库、不请求网络、不运行脚本。取消后丢弃全部结果。