别把 API Key 推上 GitHub:AI 写代码时代的密钥泄露防坑指南

整理 AI 编程和 vibe coding 流行后 API Key 泄露的风险:为什么 .env、配置文件和前端代码容易把密钥暴露到 GitHub,以及发现泄露后该如何补救。

AI 写代码降低了动手门槛,也把很多原来只会发生在工程团队里的安全问题,带到了新手和非工程用户面前。

最常见的一类事故,是把 API KeySecretToken、数据库连接串或 .env 配置文件一起推到公开仓库。对本地项目来说,这些文件只是“能让程序跑起来的配置”;一旦进了 GitHub 公共仓库,它们就变成了可以被自动扫描、自动调用、自动滥用的凭证。

密钥泄露不是小概率事件。GitGuardian 的 2026 年度报告提到,2025 年公共 GitHub 提交里出现了约 2865 万个新增硬编码凭证,AI 服务相关凭证泄露同比增长 81%。这说明问题不只是“有人粗心”,而是 AI 编程、快速原型和公开托管叠加后,泄露规模正在被放大。

为什么新手更容易泄露 Key

很多 AI Agent 或小工具都有两套“仓库”:一套在本地硬盘里,另一套在 GitHub 上。问题在于,新手经常没有意识到二者的边界。

本地运行时,config.json.envsettings.yaml 里放着 API Key,好像只是开发习惯;执行 git add .git commitgit push 之后,这些文件就可能被完整上传。仓库一旦公开,扫描机器人不需要理解你的业务,只要匹配到密钥格式,就能把它抓走。

AI 编程还会放大这个问题:

  1. AI 生成示例代码时,可能直接把 OPENAI_API_KEY = "sk-..." 这类写法放进源码。
  2. 新手为了“先跑起来”,容易把密钥硬编码在前端、脚本或配置文件里。
  3. 很多 vibe coding 平台可以直接部署应用,不一定经过 GitHub 的推送保护流程。
  4. 用户可能不知道 AI 生成的项目里到底有哪些文件、哪些接口、哪些默认权限。

换句话说,AI 可以帮你更快写出能跑的东西,但不会自动替你承担安全责任。

.gitignore 不是装饰

Git 负责版本管理,GitHub 负责托管代码,.gitignore 则是告诉 Git 哪些文件不要纳入版本历史。

一个最基本的 AI 项目,至少应该把这些内容排除掉:

1
2
3
4
5
6
7
.env
.env.*
*.key
*.pem
config.local.*
secrets.*
credentials.*

但只写 .gitignore 还不够。它只能阻止“尚未被 Git 跟踪”的文件继续进入提交。如果某个密钥文件已经被提交过,后来再把它写进 .gitignore,并不能把历史记录里的密钥抹掉。

所以更稳妥的习惯是:

  1. 新项目一开始就创建 .gitignore
  2. API Key 只放在环境变量或本地配置里。
  3. 示例文件只提供 .env.example,里面写占位符,不写真实密钥。
  4. 提交前运行一次密钥扫描工具,比如 gitleakstrufflehog 或 GitHub Secret Scanning。

Key 推上去以后,删除文件不等于安全

如果密钥已经推到公开仓库,第一反应不应该是“删掉文件再提交一次”,而应该是立刻吊销或轮换密钥。

原因很简单:Git 记录的是历史。即使你在最新提交里删除了文件,旧提交、fork、clone、缓存和扫描系统里仍可能保留那段内容。GitHub 官方文档也明确建议:如果泄露的是密码、Token 或凭证,第一步应该撤销或轮换。

处理顺序建议这样做:

  1. 立即去服务商后台吊销旧 Key,生成新 Key。
  2. 检查账单、调用日志、异常 IP 和异常用量。
  3. 从代码中移除硬编码密钥,改用环境变量或密钥管理服务。
  4. git filter-repo 或 BFG 清理仓库历史中的敏感文件。
  5. 开启 GitHub Secret Scanning 和 Push Protection。
  6. 检查 CI/CD、部署平台、云函数、前端构建产物里是否也包含旧 Key。

对于 OpenAI、Anthropic、DeepSeek、云厂商、支付、邮件、数据库等服务,泄露 Key 的后果可能不只是被刷额度,还可能包含数据读取、服务滥用、供应链污染或业务账号封禁。

前端代码里不能放真正的密钥

很多新手以为“只要页面能跑就行”,于是把 API Key 写进前端 JavaScript:

1
const apiKey = "sk-xxxxxxxx";

这基本等于公开。浏览器里的代码、网络请求、Source Map、构建产物都可以被查看。只要是真正需要保密的 Key,就不应该出现在客户端。

正确做法是让前端请求自己的后端接口,由后端读取环境变量并调用第三方 API:

1
2
3
4
5
// frontend
await fetch("/api/chat", {
  method: "POST",
  body: JSON.stringify({ message })
});

后端再使用环境变量:

1
2
// server
const apiKey = process.env.OPENAI_API_KEY;

这样做不是为了形式好看,而是为了把密钥留在服务器环境里,避免直接暴露给所有访问页面的人。

Vibe Coding 的安全责任不会自动消失

vibe coding 的问题不只是 GitHub 泄露。很多应用直接从 AI 编程平台发布到公网,跳过传统代码审查、仓库扫描和安全测试。

RedAccess 近期披露的研究显示,公开网络上可以找到大量由 AI 编程工具生成或托管的应用资产,其中一部分暴露了企业数据、个人信息或内部文件。它提醒的是同一件事:当“能上线”变得太容易,“是否应该上线”“是否只该内网访问”“是否有权限控制”就更容易被忽略。

如果你用 AI 生成应用,至少要在发布前问自己几个问题:

  1. 这个应用是否真的需要公开访问?
  2. 是否有登录、鉴权和权限隔离?
  3. 是否把数据库、API Key、Token、Webhook 地址暴露在前端?
  4. 是否限制了第三方 API 的额度、域名、权限和有效期?
  5. 是否能在发现异常后快速禁用密钥和回滚部署?

AI 写出来的代码也需要安全审查。越是“我一行代码都没写”,越不能假设它天然安全。

现在就该做的检查

可以先从自己的 GitHub 账号查起。搜索用户名加上这些关键词:

1
2
3
4
5
6
7
8
9
API_KEY
SECRET
TOKEN
OPENAI_API_KEY
ANTHROPIC_API_KEY
DEEPSEEK_API_KEY
.env
config
credentials

如果发现真实密钥,不要犹豫:先轮换,再清理。只要它进过公开仓库,就按已经泄露处理。

以后新建 AI 项目时,也建议固定一套流程:

  1. 先写 .gitignore,再写业务代码。
  2. .env.example 说明需要哪些变量。
  3. 所有密钥放环境变量,不写进源码。
  4. 给 API Key 设置最小权限、额度限制和过期时间。
  5. 开启 GitHub Secret Scanning 和 Push Protection。
  6. 发布前让 AI 再帮你做一次安全检查,但不要只相信 AI 的结论。

AI 编程真正危险的地方,不是它会写错代码,而是它让很多人第一次拥有了把不安全应用快速发布到公网的能力。写得快不是问题,把密钥、数据和权限一起交出去才是问题。

参考资料

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计