mcpField
A
actions-pinning

actions-pinning

github.com/paulnsorensen安全061 次安装1 周前更新
代码仓库

关于 actions-pinning

actions-pinning 是用于加固 GitHub Actions 供应链的技能,可扫描工作流和 Action 清单中的 uses 引用,并指导将其固定到经验证的提交 SHA。它还涵盖 Dependabot 更新以及对可变下载的风险提示。

主要功能

  1. 01扫描工作流与 Action 清单
  2. 02识别未固定及特殊引用
  3. 03核验提交 SHA 所属仓库
  4. 04配置 Dependabot 更新 Actions
  5. 05提示脚本中的可变下载风险

适用场景

  1. 01审查仓库中的 GitHub Actions 引用
  2. 02将标签或分支引用固定到提交 SHA
  3. 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.yml
evals/
evals.json
references/
policy.md
scripts/
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 自有仓库引用跳过 — 不构成供应链风险
dockerdocker://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 生态系统条目。

评论

支持 Markdown