← 中文资源

简体中文版本

在提交进入 main 之前扫描密钥

在每次推送与 Pull Request 上运行 gitleaks,发现密钥立即轮换,并在历史清理完成前阻止合并。

阅读英文原文

概述

密钥通常通过普通提交泄露:调试时提交的 .env、测试里写死的 token、粘贴到脚本中的连接串。评审者关注逻辑而非字符串,因此这些内容会顺利进入 main。一旦推送,密钥就存在于每个克隆、每份 CI 缓存,甚至每个 fork 中。提交时扫描是移除成本最低的时机。gitleaks 依据已知凭证格式与熵启发式检查差异,可在本地、pre-commit 钩子和 CI 中使用同一套规则。

步骤

  1. 本地扫描完整历史,并在输出中打码:
gitleaks detect --source . --redact --verbose
  1. CI 中只扫描本分支新增的提交:
gitleaks detect --source . --log-opts "origin/main..HEAD" --redact --exit-code 1
  1. 添加 pre-commit 钩子,让密钥连本地提交都无法产生:
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.2
    hooks:
      - id: gitleaks
  1. 先轮换凭证,再从历史中移除文件:
git filter-repo --path .env --invert-paths

验证

干净仓库的扫描应返回 0;引入测试 token 后,CI 任务应以退出码 1 失败,并只显示规则、文件与提交,不显示明文。pre-commit 钩子应在提交阶段直接拒绝。若 CI 通过而本地失败,通常是 CI 使用了浅克隆或不同提交范围,需要设置 fetch-depth: 0 并扫描正确的区间。

注意事项

  • 模式匹配与熵检测无法覆盖看起来像普通文本的密钥。
  • 从历史中删除不等于作废,轮换必须最先执行。
  • 误报只允许按具体指纹或路径加入白名单,并写明原因。
  • 密钥一旦暴露在推送中,应视为已泄露并评估影响范围。
  • 定期做一次全历史扫描,作为门禁上线前遗留问题的兜底。