第03章:AI生成了.gitignore,但我的API密钥还是提交进去了

第03章:AI生成了.gitignore,但我的API密钥还是提交进去了

"你让 AI 帮你生成了 .gitignore,里面有 .env、.key 等规则——但你的 AWS_SECRET_ACCESS_KEY 还是进了 git history。因为 .gitignore 只阻止未跟踪的文件,对已经被 git 跟踪的文件无效。密钥一旦进了 history,就必须假设它已经泄露。"*


ℹ️ 版本说明:本章基于 Git 2.54.0 + git-secrets、gitleaks。

3.1 AI默认会生成什么

你让 AI 生成 .gitignore,AI 给你一个包含常见规则的文件:

# AI 生成的 .gitignore(常见版本)
.env
.env.local
.env.*.local
*.key
*.pem
secrets/
config/secrets.json

但 AI 没告诉你:

  1. 已经被追踪的文件,加入 .gitignore 不会生效(需要先 git rm --cached
  2. 历史 commit 里的密钥,不能靠修改 .gitignore 撤销,需要用 git filter-repo 重写历史
  3. 密钥一旦 push 到远程,即使删除也必须假设已经泄露,必须立刻 rotate

3.2 AI通常遗漏的4个坑

⚠️ 坑1:.gitignore 对已追踪文件无效

# 创建了 .env 文件,里面有密钥
echo "SECRET_KEY=abcd1234" > .env

# 不小心 git add 了
git add .env
git commit -m "init"

# 这时候才想起来加 .gitignore
echo ".env" >> .gitignore
git add .gitignore
git commit -m "add .gitignore"

# 问题:.env 仍然在 git 的跟踪中!
git ls-files | grep .env  # 还是能看到 .env

正确补救步骤:

# 1. 把文件从 git 追踪中移除(但保留本地文件)
git rm --cached .env

# 2. 提交这个变更
git commit -m "chore: remove .env from tracking"

# 3. 但如果已经 push 到远程,密钥已经泄露了,必须 rotate!

⚠️ 坑2:密钥进了 history 后,删除 commit 不够

很多人以为删除包含密钥的 commit 就安全了——这是错的。

如果仓库曾经是公开的,或者有人 clone/fork 了仓库,那些旧的 commit 可能已经被爬取存储了。

只有两个措施是有效的

  1. 立刻 rotate 密钥(在 AWS/GitHub/其他服务后台撤销并重新生成)
  2. 从 history 完全清除(用 git filter-repo 重写所有历史,然后 force push)

⚠️ 坑3:没有配置预提交密钥扫描

防止密钥进入 history 的最好方法是在提交前就拦截:

# 安装 gitleaks
brew install gitleaks  # macOS
# 或从 GitHub Releases 下载

# 配置 pre-commit hook
# .husky/pre-commit
gitleaks protect --staged --redact

⚠️ 坑4:.gitignore 规则不够精确(误杀合法文件)

AI 生成的 .gitignore 有时太宽泛:

# 太宽泛:所有 .json 文件都被忽略
*.json

# 应该更精确
secrets*.json
config/production.json

或者有时不够精确,漏掉变体:

# 漏掉了带路径的情况
.env            # 只忽略根目录的 .env
# 应该是
**/.env         # 忽略所有目录下的 .env

3.3 更好的提示词

提示词 P01:生成完整的 .gitignore + 密钥防护配置

使用时机:新项目初始化,需要完整的 gitignore 和密钥防护

比默认多了什么

  • 分层 .gitignore(系统/IDE/语言/项目)
  • pre-commit 密钥扫描
  • 对已存在敏感文件的补救步骤
帮我为一个 [Python FastAPI / Node.js Next.js / 填写你的项目] 项目生成完整的 .gitignore 和密钥防护配置。

项目技术栈:
- 语言:[Python 3.13 / Node.js 24]
- 框架:[FastAPI / Next.js / Express]
- 数据库:[PostgreSQL / MySQL / MongoDB]
- 部署:[Docker / Vercel / AWS]
- IDE:[VS Code / JetBrains]
- OS:[macOS / Linux / Windows]

需要的内容:

1. 分层 .gitignore(按优先级组织):
   - 系统文件(.DS_Store, Thumbs.db)
   - IDE 文件(.vscode/, .idea/)
   - 语言相关(__pycache__/, node_modules/, .venv/)
   - 框架相关(.next/, dist/, build/)
   - 敏感文件(.env*, *.key, *.pem, secrets/)
   - 测试输出(coverage/, .pytest_cache/)

2. .gitignore 完成后的验证步骤:
   - 如何检查已被追踪的敏感文件?
   - 如果发现已追踪的 .env,如何安全地移除?

3. gitleaks 配置(防止密钥提交):
   - 安装方式(brew/npm/apt)
   - .gitleaks.toml 配置文件(排除误报)
   - 集成到 pre-commit hook(配合 husky 或 pre-commit 框架)

4. .env.example 模板:
   - 只包含变量名,不包含值(让团队成员知道需要配置哪些环境变量)

基于 Git 2.54.0。

提示词 P02:密钥泄露紧急响应

使用时机:发现密钥已经提交到 git history,需要紧急处理

比默认多了什么

  • 完整的响应步骤(不只是从 git 里删除)
  • 如何评估泄露范围
  • 从 history 清除密钥的正确工具
紧急情况:我的 [AWS密钥 / GitHub Token / 数据库密码] 被提交到了 git history。

情况描述:
- 包含密钥的 commit hash:[如果知道]
- 这个仓库是:[公开 / 私有]
- 密钥何时提交:[大约时间]
- 仓库是否有其他协作者?[是/否]

帮我制定紧急响应计划(按优先级顺序):

1. 立刻做(接下来5分钟):
   - 如何立刻 rotate/撤销这个密钥?(哪个服务,哪里操作)
   - rotate 之前能做什么检查(密钥是否被使用过)?

2. 从 git history 清除密钥:
   - git filter-repo 的完整命令(不是 filter-branch,那个是老方法)
   - 如何验证密钥已经从所有历史 commit 中移除?
   - 清除后如何 force push?(有什么风险?)

3. 通知相关人员:
   - 如果是私有仓库,其他协作者需要做什么(重新 clone)?
   - 如果是公开仓库,需要通知平台吗?

4. 事后预防:
   - 如何确保这不会再次发生(pre-commit 扫描)?

基于 Git 2.54.0。

提示词 P03:配置 GitHub Actions 的密钥扫描

使用时机:为 CI/CD 添加自动密钥扫描,防止密钥进入远程仓库

比默认多了什么

  • GitHub Actions workflow
  • 扫描结果通知
帮我配置 GitHub Actions,在每次 push 和 PR 时自动扫描是否有密钥泄露风险。

需求:
1. 触发条件:push 到任何分支 + PR 到 main
2. 扫描工具:gitleaks(开源、误报率低)
3. 扫描策略:
   - 扫描本次 commit 引入的变更(not full history,避免扫描太慢)
   - 排除测试文件里的假密钥(.gitleaks.toml 配置)
4. 扫描失败时:
   - 阻止 PR 合并(CI 失败)
   - 在 PR 里留评论说明发现了什么(但不要显示密钥内容)

给我:
- .github/workflows/secret-scan.yml 完整内容
- .gitleaks.toml 配置(排除常见误报:测试文件里的假 key、示例代码里的 placeholder)

基于 GitHub Actions + gitleaks 最新版。

3.4 验收清单

检查项 验证方法 AI辅助
.gitignore 覆盖所有敏感文件 git status 不显示 .env 等文件 用 P01 生成 .gitignore
无已追踪的敏感文件 git ls-files 不含 .env/*.key 让 AI 检查当前追踪状态
pre-commit 密钥扫描生效 故意提交含密钥文件,确认被拦截 用 P01 配置 gitleaks hook
.env.example 存在且有模板 查看仓库根目录 让 AI 生成 .env.example
GitHub Actions 密钥扫描运行 PR 里有密钥扫描 CI 记录 用 P03 配置 workflow
密钥 rotate 流程有记录 团队文档里有密钥泄露应急响应 用 P02 模板整理文档

3.5 本章小结

如果你只记一件事:密钥一旦进了 git history,就必须假设它已经泄露,必须立刻 rotate(撤销旧密钥、生成新密钥)。从 git history 删除密钥只是亡羊补牢,不能保证安全。最好的防御是 pre-commit 密钥扫描(gitleaks),在提交前就拦截。

密钥安全的三个层次

  1. 有 .gitignore(.env 文件不被追踪):防止新的密钥提交,但无法保护已追踪的文件
  2. 有预提交扫描(gitleaks + pre-commit hook):提交前自动检测密钥,本地拦截
  3. 有 CI 扫描 + rotate 流程(GitHub Actions + 密钥应急文档):纵深防御,发现即响应

→ 第4章:AI帮我用了force push,把队友的提交覆盖了