SuperAPI AI 工具集

push-gate

安全与审计

查看项目

更新于 10-13 16:58

技能介绍

用途

Push Gate 是一个形式化的预推送安全检查技能,在每次执行 git push <remote>(远程非本地文件路径)之前运行。它适用于用户要求推送、或 Claude 在向任意远程仓库执行 git push 之前。它与 git-ops(负责实际推送)互补,是紧接推送前运行的门禁。

主要能力与硬性规则

  • gitleaks 为必需依赖:未安装则输出安装说明并拒绝执行,不会静默回退到仅正则模式。
  • 任何密钥扫描命中即拒绝,无绕过标志。确认安全的发现写入仓库内提交的允许清单(gitleaks 用 .gitleaksignore,正则层用 .pushgate-allow),绝不使用内联覆盖。真实密钥会强制用户重写历史并重新调用门禁。
  • 绝不使用 --force 推送:门禁从不传递 force 标志。若用户需要强制推送,须另经明确授权单独处理。
  • 绝不使用 --no-verify:不跳过钩子。
  • 工作区必须干净:工作区脏时拒绝(未提交的工作可能被意外卷入推送流程)。
  • 远程必须具名:若 git push 未显式指定远程和分支则拒绝。

工作流

  1. 识别远程 + 分支
  2. git fetch <remote>
  3. 校验工作区干净
  4. 计算待推送提交(数量 + 列表)
  5. 检查分叉(非快进则要求用户先 rebase)
  6. 密钥扫描(gitleaks 遵循 .gitleaksignore,正则层遵循 .pushgate-allow)
  7. 禁用文件扫描(命中任意即拒绝)
  8. 体积提示、开放 issue 提示(github-ops;仅供参考,不设门禁)
  9. 显式确认
  10. git push <remote> <branch>
  11. 推送后校验(ls-remote 与推送的 SHA 匹配)

使用方式

从仓库根目录运行:

bash .claude/skills/push-gate/scripts/preflight.sh <remote> <branch>

从其他技能以不同 cwd 调用时:

bash $HOME/.claude/skills/push-gate/scripts/preflight.sh --cwd <repo-root> <remote> <branch>

--cwd 必须位于位置参数之前;省略时脚本作用于 $PWD。

脚本打印结构化报告并以退出码返回:0 全部门禁通过;1 密钥扫描命中;2 添加了禁用文件(.env、密钥文件、.claude/settings.local.json、worktree 路径等);3 工作区脏;4 非快进分叉;5 缺少依赖(gitleaks);6 未指定远程/未知远程。

依赖

  • gitleaks(必需):密钥检测,带维护的规则库。安装:Windows scoop install gitleaks 或 winget install gitleaks.gitleaks / macOS brew install gitleaks / Linux apt install gitleaks 或从 https://github.com/gitleaks/gitleaks/releases 获取二进制。
  • ripgrep(必需):正则回退层 + 禁用文件扫描。
  • git ≥ 2.30:核心操作。

两层密钥扫描都须通过:gitleaks 用维护的语料检测已知令牌格式;正则层捕获通用 password = "..." / DSN / 连接字符串模式。gitleaks 使用 references/gitleaks-config.toml(默认规则集 + 公开令牌允许清单);该文件缺失则回退到 gitleaks 内置默认配置。

触发短语

直接:"push to origin"、"push to github"、"push to remote"、"git push";疑问:"can we push?"、"safe to push?"、"ready to push?";显式:/push-gate、"run push-gate"。本地推送(git push <path> 或 git push .)不触发。

误报处理

两层密钥扫描都有仓库本地、已提交的允许清单。门禁仍拒绝任何未显式允许的命中,且不提供内联绕过。gitleaks 使用 .gitleaksignore(指纹格式 commit:file:rule:line);正则层使用 .pushgate-allow,格式为 <repo-relative-path>:<line-regex>,每行一条,允许 # 注释,每条须在上方附原因注释,条目按第一个冒号分割,无行号;条目仅抑制该文件的命中。拒绝时扫描器为每个命中打印现成的锚定条目。文件已不存在或正则不再匹配的条目会报告为过期(警告,非门禁)。示例:

# reason: test fixture — wire-snapshot key exercised by MCP wire tests, not a credential
packages/mcp/test/client.test.ts:^  apiKey: "wire-snapshot-key",$

不在范围内

发布自动化(changelog、打标签、版本升级)属于 ci-cd-ops / git-ops;完整安全审计属于 security-ops(更广的 SAST + 依赖扫描);强制推送/历史重写被有意排除,需明确的带外授权;签名提交校验暂未纳入,视需要后续添加。

文件

  • SKILL.md:工作流 + 规则
  • scripts/preflight.sh:主编排(步骤 1–8)
  • scripts/scan-secrets.sh:gitleaks + 正则层(步骤 6)
  • references/secret-patterns.txt:正则语料 + 误报过滤词
  • references/gitleaks-config.toml:gitleaks 配置(默认规则 + 公开令牌允许清单)
  • tests/run.sh:密钥扫描器的离线行为自测
  • assets/:(空;预留报告模板) 逐仓库(不随技能发布):.gitleaksignore 和 .pushgate-allow,提交在被扫描仓库根目录。