关于 actions-pinning
actions-pinning 是用于加固 GitHub Actions 供应链的技能,可扫描工作流和 Action 清单中的 uses 引用,并指导将其固定到经验证的提交 SHA。它还涵盖 Dependabot 更新以及对可变下载的风险提示。
主要功能
- 01扫描工作流与 Action 清单
- 02识别未固定及特殊引用
- 03核验提交 SHA 所属仓库
- 04配置 Dependabot 更新 Actions
- 05提示脚本中的可变下载风险
适用场景
- 01审查仓库中的 GitHub Actions 引用
- 02将标签或分支引用固定到提交 SHA
- 03为 Actions 提交配置 Dependabot 更新
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ paulnsorensen/ git-gouda --skill actions-pinning安装后在 Claude Code 中输入/actions-pinning确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/dependabot-actions-snippet.ymlevals/evals.jsonreferences/policy.mdscripts/pin_check.py详细介绍
actions-pinning
将 GitHub Actions 工作流、复合操作和可复用工作流中的每个 uses: 引用固定到提交 SHA,验证每个 SHA 是否属于所声明的操作仓库,并通过 Dependabot 保持固定版本为最新。
本技能仅涵盖供应链固定。/oss-hygiene 负责对相同的工作流文件进行 Token-Permissions 和 Dangerous-Workflow 加固;/ci-optimize 负责提升实际运行速度。请分别运行这些技能。
协议
1. 清点
运行随附的扫描器,检查每个工作流文件和复合操作/可复用工作流文件:
python3 scripts/pin_check.py .
扫描器会遍历 .github/workflows/**、.github/actions/**,以及树中的每个 action.yml 或 action.yaml 清单。它会跳过版本控制和依赖目录:.git、.hg、.svn、node_modules、.venv、venv、__pycache__、dist、build、.tox 和 target。它会扫描 vendor/,因为 ./vendor/... 引用可能会运行供应的操作。扫描器会为每一行 uses: 打印 (file, line, action, ref, status) 表格;若存在任何未固定的引用,则以状态码 1 退出。使用 --json 可在编写脚本执行后续步骤时获取机器可读输出。
扫描器使用正则表达式,而非 YAML 解析器。它会从每个 uses: 值中移除一对匹配的外围引号。扫描器有两个已知局限;遇到任一情况时,请手动检查工作流:
run: |块标量中的uses:行会产生误报。- 流式映射(例如
- {uses: owner/repo@v1})不会产生任何行。
2. 分类
扫描器会为每个引用分配一种状态:
| 状态 | 含义 | 所需操作 |
|---|---|---|
pinned-sha | 已是完整的 40 字符提交 SHA | 无 |
unpinned-tag | 标签格式的引用,例如 v4 或 v4.1.0 | 解析为 SHA |
unpinned-branch | 常见分支名称,例如 main | 解析为 SHA |
unpinned-ref | 其他任何引用,例如 release/v1;类型未知 | 解析为 SHA |
unpinned-commit | 类似提交的十六进制引用,例如短 SHA de0fac2 或大写的 40 字符 SHA | 解析为完整的小写 SHA |
missing-ref | 完全没有 @ref | 解析为 SHA |
invalid-self-ref | 带有 @ref 后缀的 $/path 自有仓库引用 | 移除 @ref 后缀 |
local | 本地 ./path 操作或 $/path 自有仓库引用 | 跳过 — 不构成供应链风险 |
docker | docker://image 引用 | 单独标记 — SHA 固定针对镜像摘要,而非此扫描器 |
3. 将每个引用解析为提交 SHA
对于每个 unpinned-tag、unpinned-branch、unpinned-ref、unpinned-commit 或 missing-ref 结果:
# Tag: the ref object is the commit (lightweight) or a tag object (annotated).
gh api repos/{owner}/{repo}/git/ref/tags/{tag} --jq '.object'
# Branch: the ref object is the commit directly.
gh api repos/{owner}/{repo}/git/ref/heads/{branch} --jq '.object.sha'
# Annotated tag: dereference the tag object to get the commit SHA.
gh api repos/{owner}/{repo}/git/tags/{tag_sha} --jq '.object.sha'
对于 unpinned-ref,先尝试 tags/ 路径,再尝试 heads/ 路径。
对于 unpinned-commit,标签和分支路径无法解析该引用。请通过 commits 端点解析,它会返回完整的小写 SHA:
gh api repos/{owner}/{repo}/commits/{ref} --jq '.sha'
冒名提交检查 — 重写固定值之前务必执行。 确认解析出的 SHA 确实属于操作自身的仓库,而非复刻仓库、被重写的引用或伪造的值:
gh api repos/{owner}/{repo}/commits/{sha}
此处返回 404 表示该 SHA 不属于该仓库。请停止并重新解析;不要写入未经验证的 SHA。
验证通过后,重写该行:
uses: owner/repo@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
保留原始标签作为行尾注释 — 它是便于人类阅读的版本标记;SHA 才是实际强制执行的固定值。
4. 使用 Dependabot 保持固定版本最新
将 assets/dependabot-actions-snippet.yml 中的 github-actions
生态系统条目添加到现有的 dependabot.yml 中,或与现有文件合并。Dependabot
会自动将标签更新解析为新的提交 SHA,并创建 PR,同时更新版本注释——请审核并合并这些 PR,而不是之后手动编辑固定版本。
截至 2026-07-14,版本更新(非安全更新)默认设有 3 天的
注册表可用性冷却期;新发布的标签在度过此窗口期之前,不会出现在 Dependabot PR 中。来源见
references/policy.md。
如需涵盖仓库中所有生态系统的完整 dependabot.yml 框架,请使用 /oss-hygiene——此技能仅负责 github-actions
条目。
5. 仓库和组织的固定版本策略
GitHub 可在允许的操作策略层级(仓库、组织或企业)强制要求固定到 SHA,包括直接禁止特定操作。在提出任何变更之前,请先查看请求所涉及范围内的当前策略:
# Repository scope.
gh api repos/{owner}/{repo}/actions/permissions
# Organization scope. Use this for an organization-wide request.
gh api orgs/{org}/actions/permissions
这些是读取操作。未经用户明确授权进行相应的特定变更,切勿调用对应的写入端点
(PUT repos/{owner}/{repo}/actions/permissions、
PUT orgs/{org}/actions/permissions 以及 selected-actions /
allowed_actions 变体)——策略变更可能导致其他工作流无法运行。
SHA 固定策略仅适用于操作。在该策略下,可复用工作流仍可使用标签,因此此技能会自行固定可复用工作流引用。
6. 标记工作流脚本中的可变下载
正则表达式固定检查仅涵盖 uses:。读取每个工作流时,也要标记任何通过 run: 步骤、在固定操作机制之外获取代码的情况(仅报告发现,不重写):
curl ... | sh或curl ... | bash:将远程脚本直接通过管道传给 shell。wget从没有版本或校验和的 URL 下载内容。pip install package(或npm install、gem install等)未固定版本。
这些问题与未固定的操作一样,属于供应链风险,但修复方式因生态系统而异,且往往会改变构建行为——请报告,不要重写。
7. 可选:zizmor
如果已安装 zizmor,请运行它作为第二种意见来源(它还会检查本扫描器未涵盖的
bot-conditions 和复合操作内部内容):
zizmor .github/workflows/
如果未安装,请静默跳过——它是可选工具,不是必需的门槛。
8. 验证
每批重写后都要重新运行扫描器:
python3 scripts/pin_check.py . && echo "all uses: references pinned"
如果退出代码为 0,且没有 unpinned-tag、unpinned-branch、unpinned-ref、
unpinned-commit、missing-ref 或 invalid-self-ref 行,则表示所有可处理的引用均已固定。请单独报告 local 和 docker 行——这些仅供参考,不代表失败。
此技能不适用于
- 加固
Token-Permissions和Dangerous-Workflow(最小权限permissions:块、pull_request_target风险、将${{ github.event.* }}插值到 shell 中)——请使用/oss-hygiene。 - 提升 CI 运行速度——请使用
/ci-optimize。 - 为非 Actions 生态系统选择或编写完整的
dependabot.yml——请使用/oss-hygiene。 - 未经仓库所有者明确授权进行相应的特定写入操作,就应用组织范围的允许操作策略。
参考资料
references/policy.md——关于uses:语法、 SHA 固定、允许的操作策略、SHA 解析端点、 Dependabot 冷却期和 zizmor 的主要来源引用。scripts/pin_check.py——步骤 1、2 和 8 中使用的清单与分类扫描器(--self-test运行其内嵌测试样例;--json输出机器可读结果)。assets/dependabot-actions-snippet.yml——dependabot.yml的github-actions生态系统条目。