150 万人被偷家之后,我翻了翻自己的 API Key 管理,冷汗直流 😰

14 阅读4分钟

今天刷掘金热榜,看到那篇 VS Code 插件供应链攻击的文章直接给我整不会了——两个"浓眉大眼"的 AI 编程插件,150 万安装量,背地里偷代码、偷 API Key、偷 SSH 密钥,偷得明明白白。

我当时的反应:

卧槽,我自己的 key 是不是也在裸奔?

然后我花了一个下午,把自己电脑上所有跟 AI 相关的 key 全翻了一遍。

结论:比我想象的严重 10 倍。

先说说我的"案发现场"

我是独立开发者,平时写代码重度依赖各种 AI 工具。翻了一下,我的 API Key 散布在以下地方:

# .env 文件(4个项目里各有一份)
OPENAI_API_KEY=sk-xxxx
ANTHROPIC_API_KEY=sk-ant-xxxx
GOOGLE_AI_KEY=AIzaSy-xxxx

# ~/.zshrc(是的我干了这种蠢事)
export DEEPSEEK_API_KEY="sk-xxxx"

# VS Code settings.json
"copilot.apiKey": "xxx"

# 某个 Jupyter Notebook 里硬编码的
client = OpenAI(api_key="sk-proj-xxxxx")

# Chrome 密码管理器里存的各平台 dashboard 密码
# ...懒得数了

数了一下,7 个不同平台的 API Key,分散在至少 12 个文件里。有的还提交过 git(虽然后来 force push 删了,但 GitHub 的搜索引擎可不会帮你删缓存 🫠)。

被偷家的三种姿势

看完那篇供应链攻击分析,我总结了下 API Key 被盗的三大路径:

1. 插件/扩展偷你 🔌

就是今天热搜上的这种。AI 编程插件天然需要读你的代码文件,你根本分不清它是在"帮你补全"还是在"偷你文件"。

恶意插件的操作:

  • 监控 onDidChangeTextDocument,每次你编辑文件就把内容传出去
  • 批量扫描 .envconfig.json、SSH 密钥
  • 用零像素 iframe 做用户画像

最恐怖的是:这些插件功能完全正常,能用,好用,你完全不会怀疑它。

2. 项目文件泄露 📁

这个是我自己的血泪教训:

# 你以为 .gitignore 了就安全?
$ git log --all --full-history -- "*.env"
# 惊不惊喜,意不意外
commit 3a7f2d1  Add environment config
    .env | 15 +++++++++++++++

Git 历史是永久的。我之前有个项目忘了 gitignore .env,push 之后才发现,虽然马上删了,但那个 commit 还在历史里。GitHub 的代码搜索能搜到,各种爬虫也能搜到。

后来我装了 gitleaks 做 pre-commit 检查,现在每次 commit 前自动扫描敏感信息:

# 安装 gitleaks
brew install gitleaks

# 扫描历史提交
gitleaks detect --source . -v

# 作为 pre-commit hook
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.21.0
    hooks:
      - id: gitleaks

3. 多平台 Key 管理混乱 🔑

这个是独立开发者的通病。你同时用 OpenAI、Anthropic、Google、DeepSeek、Moonshot……每个平台一套 key,每个项目一份 .env

问题来了:

  • 你怎么知道哪个 key 还在用?
  • 哪个 key 额度快用完了?
  • 哪个 key 可能已经泄露了?
  • 某个平台 API 挂了,你怎么快速切换?

我之前的方式是全手动管理——一个 Notion 表格记着所有 key。你猜怎么着?Notion 链接分享的时候不小心开了公开访问 😇 还好及时发现了。

我的解决方案(踩了一个月的坑总结的)

折腾了一圈,我现在的 key 管理方案分三层:

第一层:本地环境加固

# 1. 所有 key 统一放 .env,不放 .zshrc
# 2. .gitignore 必须包含
.env
.env.*
*.pem
*.key

# 3. gitleaks pre-commit hook(上面说了)

# 4. 定期扫描
gitleaks detect --source ~/projects -v --no-git

第二层:用密钥管理工具

macOS 用户可以用 Keychain:

import keyring
# 存
keyring.set_password("openai", "api_key", "sk-xxxx")
# 取
key = keyring.get_password("openai", "api_key")

或者用 direnv + .envrc

# .envrc(自动加载,离开目录自动卸载)
export OPENAI_API_KEY=$(security find-generic-password -s "openai-key" -w)

第三层:用聚合平台统一管理

这是我最近发现的思路,也是对我帮助最大的。

与其管 7 个平台的 key,不如只管 1 个。

现在有一些 AI 模型聚合平台,一个 API Key 就能调 GPT-4o、Claude、Gemini、DeepSeek 等几十个模型。我试了几家,目前主要在用的方案:

特点分散管理聚合平台
Key 数量7+ 个1 个
泄露风险高(散布各处)低(一个入口)
模型切换改代码 + 换 key改一个参数
额度监控各平台分别看统一 dashboard
国内访问GPT/Claude 要翻墙直连(有国内节点的话)

我现在个人项目的调用方式统一成了 OpenAI 兼容格式,换模型只改 model 参数:

from openai import OpenAI

# 一个 key,几十个模型随便切
client = OpenAI(
    api_key="your-one-key",
    base_url="https://api.ofox.ai/v1"  # 聚合平台地址
)

# 用 GPT-4o
resp = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "hello"}]
)

# 切 Claude?改一行
resp = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "hello"}]
)

# 切 DeepSeek?再改一行
resp = client.chat.completions.create(
    model="deepseek-chat",
    messages=[{"role": "user", "content": "hello"}]
)

不用管每个平台的 SDK 差异、不用管翻墙、不用管 key 过期轮换,对于我这种同时用好几个模型的人来说简直是救命。而且最关键的——我只需要保护好一个 key,安全管理的复杂度直接降了一个量级。

最后的碎碎念

说真的,今天那篇供应链攻击的文章让我挺后怕的。我们每天用各种 AI 工具写代码,却很少想过这些工具本身是否安全。

几个 takeaway:

  1. VS Code 插件不是装越多越好。不用的赶紧删,尤其是那些要读你代码的 AI 插件,认准官方的
  2. 别在 .zshrc 里 export API Key 了,真的会被读到的
  3. gitleaks 装一个,5 分钟的事,可以救你一命
  4. Key 管理要集中化,散落在 12 个文件 7 个平台的 key,你迟早管不过来
  5. 定期轮换 Key,别一个 key 用一年从不换

你的 API Key 管理方案是什么样的?有没有踩过类似的坑?评论区聊聊 👇


作者是一名独立开发者,日常折腾 AI 编程工具和各种大模型 API。关注我,下次聊聊 Vibe Coding 的正确打开方式。