[控场AI]
· 10 分钟阅读· 5,440 字

OpenAI/Claude/Gemini API Key安全防护实战清单

OpenAI/Claude/Gemini API Key安全防护实战清单

LLM API Key 持有即有权计费,需拆分、过期、硬上限与服务端隔离。

文章以 OpenCode Console 的 API Key 泄露事件为引子,指出 LLM API Key 与传统密码的本质区别:它是持有即生效的计费凭证,泄露后没有二次验证或登录入口作为缓冲,损失呈开放式增长。围绕 OpenAI、Anthropic、Google 三家的官方文档,文章梳理出一条完整防线:按工具、项目与环境拆分多把 Key 以缩小爆炸半径;利用创建时过期与组织策略强制轮换,并提前演练以摸清 Key 的所有存放位置;用硬性支出上限取代仅能事后通知的告警;通过 server-only、后端鉴权限流与 IP 白名单确保 Key 只存在于服务端;审慎对待把 Key 粘贴进第三方托管工具的行为,因为在工具内删除并不等于吊销。最后给出泄露后第一小时的处置顺序。

OpenCode Console 的一次安全事件,让 1.4% 的用户暴露了第三方模型提供商的 API Key。Anthropic 和 Google 在数小时内吊销、封禁了相关密钥,OpenCode 至今未说明攻击路径。这场风波最有价值的提醒不是"谁出事了",而是一个被反复验证的常识:LLM API Key 是一种持有即有权使用的凭证,谁拿到那串字符,谁就能花你的钱,直到提供商把它吊销为止。

据 The Hacker News 报道以及 OpenAI、Anthropic、Google 三家官方文档(截至 2026 年 10 月),下面这套清单覆盖了从密钥创建、存储、限额到泄露后第一小时处置的完整链条。

为什么 API Key 泄露的代价是开放式的

传统密码泄露后,攻击者通常需要找到可登录的入口;而 API Key 泄露后,攻击者直接拥有了计费能力。没有二次验证,没有 IP 绑定(除非你主动配置),没有"异地登录提醒"。

更麻烦的是,很多团队把同一把 Key 同时用在脚本、Agent、SaaS 工具和生产环境中。一旦泄露,吊销这把 Key 等于让生产停摆,于是团队倾向于"先观察一下",而观察的每一分钟都在产生账单。

按工具、项目和环境拆分成多把 Key,是降低单点爆炸半径的第一步。撤销一把 Key 只影响一个消费者,而且用量页面能直接告诉你是哪个消费者被滥用了。

三家提供商的组织方式差异

  • OpenAI:Key 归属于 project。官方 Key 安全文章明确说明共享 Key 违反服务条款,并且可以给单把 Key 分配权限。
  • Anthropic:Workspace 用于隔离环境和支出。新 Key 分为个人 Key(以你的身份行事)和服务账户 Key,两者都可以限定到单个 Workspace。个人 Key 在所有者离开组织时自动失效——这正是你想要的行为。旧的 Workspace Key 已被标记为 legacy。
  • Google:每把 Gemini Key 都属于一个 Google Cloud 项目,该项目下所有 Key 的用量合并计入项目的支出上限。想让每个工具有独立上限,就得建独立项目。

BYOK(Bring Your Own Key) 是本文反复出现但未展开的模式:用户把自己在模型提供商处的 API Key 填入第三方工具,由该工具代为发起模型调用。它的吸引力在于用户可以直接沿用自己已有的计费与配额,而不必为工具单独付费;但代价是 Key 的持有权与使用权发生分离——Key 属于用户,调用行为却由工具服务器执行。因此任何 BYOK 工具在设计上都面临同一组问题:Key 落库时是否加密、解密能力被授予哪些角色、面板用户能否读回明文。理解这一点,就能明白为什么「在工具里删除 Key」与「在提供商侧吊销 Key」是两件完全不同的事。

让 Key 会过期,并演练一次轮换

永不过期的 Key,只要还有一份副本存在,就永远有效。

OpenAI 的项目 Key 可以在创建时设置过期日期,管理员还能在组织或项目层面强制最大 Key 生命周期。Anthropic 在创建时要求选择有效期:3 小时、1 天、7 天、30 天、自定义或永不过期;创建后无法修改,组织策略可以禁用"永不过期"选项,有效期不少于 14 天的 Key 会在到期前 7 天邮件提醒创建者。

Google 的 Gemini Key 文档没有提到过期机制,而是用另一种方式收紧:自 2026 年 5 月 28 日起,新的 AI Studio Key 默认绑定服务账户并限制为仅可调用 Gemini API,不受限的标准 Key 会被拒绝。

API Key 安全管理示意图

OpenAI 和 Google 给出的轮换顺序一致:创建替代 Key → 部署 → 验证可用 → 吊销旧 Key。关键在于在平静的日子里先演练一遍,搞清楚这把 Key 究竟存在于哪些地方——生产环境、预览环境、CI、那个没人记得的 cron 任务——而不是在事故压力下才发现漏了一处。

两家还都提供了 workload identity federation:在支持的云工作负载上,用短期令牌替代存储的 Key,本质上是"没有东西需要轮换的轮换"。

Workload identity federation(工作负载身份联合) 是替代长期密钥的主流方案。其基本机制是:云平台(如 AWS、GCP、Azure)为运行中的工作负载签发短生命周期的身份令牌,模型提供商信任该身份提供方,直接以令牌换取临时访问凭证。整个过程中不存在需要写入环境变量或配置文件的静态 Key,因此也没有「泄露后被长期滥用」的窗口。它并非完全不需要轮换,而是把轮换从人工操作变成了平台自动完成的事情——令牌过期即失效,新的令牌由运行时自动获取。对已经运行在云上的服务,这是优先级最高的改造方向之一。

硬性支出上限,而不是告警

OpenAI 那篇文章说得很直白:"仅靠支出告警无法阻止 API 流量。"凌晨三点收到一封邮件,只是已经花掉的钱的一张收据。

提供商硬性上限文档中的注意事项
OpenAI组织或项目级月度支出上限,强制生效执行不是瞬时的;硬上限也可能挡住正常请求
AnthropicWorkspace 级月度支出上限,低于组织上限无法在 Default Workspace 上设置
GoogleAI Studio 项目月度支出上限,外加按结算账户的层级上限实验性功能,约 10 分钟延迟;批处理任务和 Agent 会话可能超支

自动充值同理。Anthropic 的 Key 最佳实践把自动充值上限视为泄露 Key 的防护措施,Google 的 Prepay 方案也有月度自动扣款上限。不设上限的自动充值,就是一张不设上限的信用卡。

自己构建 Agent 的团队还应在代码层加一道闸。开源项目 Claient 的做法是:当账户使用平台 Key 时,webhook 在每一轮对话前原子性地预留预算,达到月度上限就停止回复。这个 kill-switch 思路对自建 Agent 同样适用。

Key 只能待在服务端

OpenAI 和 Google 都说得很清楚:不要在浏览器或移动端代码中放 Key,把调用路由到你的后端。

在 Next.js 里,分界线就是 NEXT_PUBLIC_ 前缀。Next.js 在构建时会把带这个前缀的值内联进 JavaScript 包——一把带 NEXT_PUBLIC_ 的 LLM Key,就是一把已公开发布的 Key。

正确的做法是用 server-only 包做编译期防护:

// lib/llm.ts
import 'server-only'; // 从客户端组件导入会直接导致构建失败
import Anthropic from '@anthropic-ai/sdk';

export const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

后端路由同样需要鉴权和限流。一个公开的、替你转发 Key 的路由,用的仍然是你的 Key:

// app/api/chat/route.ts
import { anthropic } from '@/lib/llm';

export async function POST(req: Request) {
  // 先做鉴权和限流
  const { message } = await req.json();
  const res = await anthropic.messages.create({
    model: MODEL,
    max_tokens: 512,
    messages: [{ role: 'user', content: message }],
  });
  return Response.json(res.content);
}

如果后端有固定出口 IP,再加一层 IP 白名单。OpenAI 的 IP 白名单按组织或项目生效,非白名单 IP 即使持有有效 Key 也会收到 401 ip_not_authorized;Google 可在 Cloud 控制台的 Application restrictions 下把 Key 限制到具体 IP;Anthropic 则为企业版用户通过支持渠道提供 IP 白名单。

NEXT_PUBLIC_ 前缀之所以危险,与 Next.js 的构建模型有关。Next.js 在构建阶段会把 process.env 中以该前缀开头的变量值直接替换进客户端 bundle 的字面量,运行时并不存在「服务端读取环境变量再下发」的环节。这意味着一旦打上这个前缀,密钥就会以明文形式出现在浏览器可下载的 JavaScript 文件里,任何人打开开发者工具或抓取静态资源都能拿到。相对地,server-only 包通过一个在客户端环境中会抛出错误的入口模块,把这个约束提前到编译期:只要服务端模块被客户端组件引用,构建就会失败,而不是等到上线后才发现密钥已随包发布。

把 Key 粘贴进托管面板前,先想清楚

Anthropic 帮助中心有一句最诚实的话:当你把 API Key 上传到第三方工具时,"你等于把 Claude Console 账户的访问权交给了那个工具的开发者"。这不是针对 OpenCode 的评论,而是所有用你的 Key 调用模型的托管工具的共同属性。而且,在工具里删除 Key 并不会吊销它——只有提供商能吊销。

Claient 接受客户自带的 Claude Key(BYOK),作者正好站在另一侧。它的实现是:Key 存入 Supabase Vault,设置表只保留 secret 的 id;能返回解密 Key 的函数只能由 webhook 使用的 service_role 执行,任何面板用户(包括所有者)都无法读回,UI 也不会再次展示。如果客户的 Key 被吊销,机器人会回退到平台 Key 并通知商家,而不是静默失败。这限制了面板漏洞可能泄露的范围,但并不能让 Key 在服务器被攻陷时不可窃取——没有方案能做到这一点。

站在用户一侧,可操作的建议是:给每个托管工具一把专属 Key,放在独立项目或 Workspace 里,设低上限和过期时间,并问清供应商三个问题——Key 存在哪里、是否加密、谁能解密。

泄露后的第一个小时

  1. 在提供商侧吊销,而不是在工具里删。 OpenAI 建议立即从 API Keys 页面轮换;Claude Console 中 Disable 可逆、Delete 永久。如果 Key 正在被滥用,先吊销,接受几分钟停机。"先建后删"只适合计划内轮换。
  2. 规范地签发替代 Key。 放进正确的项目或 Workspace,设置过期时间,部署到旧 Key 曾出现的所有位置。
  3. 按 Key 查看用量,回溯到 Key 可能泄露的最早日期,而不只是今天。
  4. 调查期间先调低支出上限。
  5. 定位泄露点再修复。 Git 历史(后续提交里删除文件并不等于移除)、CI 和错误日志、任何你粘贴过它的工具。
  6. 联系账单支持,提供 Key ID、日期和事件经过。OpenAI 的文章指向 help.openai.com。

常见问题

支出告警能保护泄露的 API Key 吗?

不能。告警只告诉你钱正在被花,不会阻止它。需要硬上限:OpenAI 的强制支出限额、Anthropic 的 Workspace 支出上限、Google AI Studio 的项目支出上限。它们都不是瞬时的,但能把一张开放式账单变成有边界的账单。

把 API Key 粘贴进第三方工具安全吗?

只有当你能接受把提供商账户交给该供应商时才安全,因为这正是你实际在做的事。如果要用,给它一把专属 Key,放在独立项目或 Workspace,设低上限和过期时间。在工具里删除 Key 不会吊销它。

如何轮换 Anthropic API Key?

在 Claude Console 创建一把带过期时间的新 Key,部署到旧 Key 的所有使用位置,确认可用后禁用(可逆)或删除(永久)旧 Key。过期时间在创建时选定,之后无法修改。

这套配置没有任何激动人心的地方,而这正是它的意义:无聊的默认设置,才能让别人的安全事故停留在新闻里,而不是变成你的账单。

#OpenAI API Key 安全#Claude API Key 轮换#Gemini API Key 保护#API 密钥泄露处理#API 支出上限#NEXT_PUBLIC 密钥泄露#BYOK 安全#LLM API 安全最佳实践
分享:

相关推荐