在使用 gitleaks
扫描仓库时意外发现,项目早期的若干提交中包含了一些 Secret Key。整改时,大多数密钥可以通过吊销并重新生成解决,但阿里云云市场中的某个服务的 API 密钥既无法吊销也无法重置,只能设法彻底清理仓库历史中的敏感信息。
本文主要参考 GitHub 官方文档 Removing sensitive data from a repository - GitHub Docs,以下示例均以 GitHub 仓库为背景。
整个清理流程包括以下三个步骤:
- 使用 git-filter-repo 在本地重写存储库
- 从 GitHub 中完全删除数据
- 与同事协调清理现存的其他克隆
风险提示
由于清理过程会从引入敏感信息的 commit 开始重建 Git 历史,因此会产生一些副作用(详见上述官方文档)。这些副作用包括但不限于:分支保护规则会被关闭、其他协作者的工作内容可能丢失、历史 PR 的 diff 信息失效等。
使用 git-filter-repo 在本地重写存储库
首先安装 git-filter-repo
工具:
brew install git-filter-repo
克隆仓库并进入目录:
git clone https://github.com/YOUR-USERNAME/YOUR-REPOSITORY
cd YOUR-REPOSITORY
若要删除包含敏感信息的整个文件,执行以下命令:
git-filter-repo --sensitive-data-removal --invert-paths --path GIT-PATH
若要删除指定文本,需先准备一个敏感内容词表。词表支持正则表达式、glob 模式和指定替换后文本等配置1,之后执行清理:
git-filter-repo --sensitive-data-removal --replace-text ../passwords.txt
执行完成后,需要记录以下数据供下一步使用:
输出中的 First Changed Commit
输出中的 Orphaned LFS objects
受影响的 PR ref 数量,可通过以下命令查看:
grep -c '^refs/pull/.*/head$' .git/filter-repo/changed-refs
确认更改结果无误后,需先关闭 GitHub 分支保护规则,然后强制推送到远端:
git push --force --mirror origin
从 GitHub 中完全删除数据
通过 GitHub Support portal 向 GitHub 提交工单,需要提供以下信息:
- 仓库的 owner 和 name
- 上一步中收集的 First Changed Commit
- 上一步中收集的受影响的 PR ref 数量
- 上一步中收集的 Orphaned LFS objects
GitHub 官方人员会对受影响的分支引用和 LFS 文件进行清理。
与同事协调清理现存的其他克隆
所有该项目的协作者应该重新克隆项目,或者使用 rebase 方式进行 pull(而非 merge),避免将旧代码重新引入造成污染。
小结
完成上述步骤后,还需恢复之前禁用的分支保护规则。
整个过程并不算特别复杂,但对于大型项目而言,需要协调一个所有协作者都能配合的时间窗口,确保清理工作顺利完成。