要点速览
API Key(API 密钥)是一串让服务辨认「这个请求是哪个账号送出的」的字符串,程序把它附在每次请求里,服务就依此授权与计费。它像信用卡号:任何人拿到都能用你的额度,费用算在你头上。保管的重点是不让它出现在代码、Git 纪录、截屏与对话里,改用环境变量存放,并分开用途、设置用量上限;一旦外泄,第一步永远是立刻撤销。
API Key 是什么?简单说,它是一串让服务辨认「这个请求是哪个账号送出的」的字符串。你写的程序、用的 AI 工具要调用 OpenAI、Anthropic、Google 这类服务时,都会把它附在请求里,服务就依此决定要不要处理、以及要把费用算给谁。这篇不绑定特定服务商,讲的是每一家都通用的观念:API Key 的用途、为什么外泄等于让别人花你的钱、最常外泄的地方,以及保管与出事时的处理方法。
API Key 是什么?
先定义两个名词。API(应用程序界面)是让程序之间互相沟通的约定;API Key(API 密钥)则是这个沟通过程中,用来证明身分的那串字。
它和你平常登录用的密码不太一样:
| 密码 | API Key | |
|---|---|---|
| 谁在用 | 你自己,登录时输入 | 程序,每次请求都附上 |
| 用来做什么 | 进入你的账号 | 让程序以你的账号调用服务 |
| 可以有几个 | 通常一个账号一组 | 可以替不同用途各建一把 |
| 出事时 | 改密码 | 禁用那一把,再建新的 |
Anthropic 的官方说明用了一个很好懂的比喻:API Key 就像信用卡号,任何人拿到并使用,产生的费用都算在你头上。所以问题不在于「别人会不会猜到」,而在于「它会不会被你自己不小心放到别人看得到的地方」。
如果你还没实际调用过 API,可以先看 第一次调用 LLM API,那篇示范了密钥放在请求的哪里;这篇专讲怎么保管。
为什么外泄这么严重?
GitHub 的文档把外泄的后果分成几类,对个人用户最直接的是两种:
- 账单:别人用你的密钥调用服务,费用由你支付。如果你没有设置用量上限,损失可能远超出你的预期。
- 数据:依那把密钥的权限,对方可能读到或改动你放在该服务里的数据。
还有一个容易被忽略的特性:外泄之后,你很难确定它「到底传到了哪里」。GitHub 指出,公开保存库里的秘密会被搜索引擎和专门的扫描服务索引。所以处理外泄的思路,不是「把它藏回去」,而是「让它失效」。
API Key 最常外泄的 8 个地方
下面这张表是本站整理的常见情况,不是官方标准;每一列的依据都附在文末的链接里。
| 外泄的地方 | 怎么发生的 | 怎么预防 |
|---|---|---|
| 代码里 | 测试时把密钥直接写在程序里,后来一起提交 | 程序只读环境变量,代码里永远不出现密钥 |
.env 档被提交 | 忘了把 .env 加进 .gitignore | 第一次提交前就设好 .gitignore,并用指令确认 |
| README、文档、范例 | 范例设置里放了真的密钥 | 范例只用明显的假值 |
| GitHub 的 Issue 与 PR 留言、论坛、Email、客服工单 | 求救时把错误消息连同密钥一起粘贴 | 贴之前先把密钥删掉;Anthropic 提醒连对它的客服都不要给 |
| 截屏、录像、直播 | 画面上刚好开着含密钥的文件或终端机 | 录制前关掉这些窗口,发布前再检查一次画面 |
| 贴进 AI 对话,或让 AI 代理读到 | 请 AI 调试时整段设置粘贴;代理读了项目里的 .env | 不贴密钥本身;限制代理读取机密文件 |
| 前端(浏览器)代码 | 密钥写在网页的 JavaScript 里 | 密钥只放在服务器端,由服务器代为调用 |
| 自动化流程的纪录 | 自动化流程或脚本把密钥印进纪录(log) | 不印出密钥;用平台提供的秘密保存功能 |
几个需要多说明的地方:
前端代码:网页上的 JavaScript 会下载到每个访客的浏览器里运行,所以写在里面的密钥,等于公开给所有访客。Anthropic 的 TypeScript SDK(官方提供给 TypeScript 程序使用的套件)就因此预设禁用在浏览器里运行,理由正是避免暴露密钥。
AI 代理:AI 代理会读你的文件、运行指令。如果密钥放在它的工作文件夹里,它就可能读到,并把内容放进对话里。Claude Code 的文档提供了用拒绝规则禁止读取 .env 的做法;更完整的原则请看 让 AI 代理安全操作电脑。
共用一把密钥:Anthropic 的建议是,每个需要使用 API 的人都应该有自己的密钥。共用的密钥一旦外泄,你无法知道是谁那里出的问题,也无法只禁用其中一人。
保管的基本功:环境变量与 .env
环境变量(Environment variable)是操作系统提供给程序读取的「名称=值」设置。把密钥放在环境变量里,代码里只写「去读某某变量」,密钥本身就不会出现在代码中。
这个做法来自一份广为引用的软件开发方法论〈The Twelve-Factor App〉:设置(包括外部服务的凭证)要和代码严格分开,存在环境变量里。它提供了一个好用的自我检查:如果你的代码现在立刻公开,会不会泄漏任何凭证? 会的话,就表示密钥还放错地方。
环境变量怎么设置、Windows 和 Mac 有什么不同,请看 终端机基础。
.env 档
每次都手动设置环境变量很麻烦,所以很多项目会用 .env 档:一个把环境变量以「名称=值」逐行写下的纯文字档,程序启动时由套件读进来(Anthropic 的说明以 Python 的 python-dotenv 套件为例)。内容大概长这样:
MY_SERVICE_API_KEY=这里放你的密钥
.env 档方便,但它本身就是一个「密钥明文存在硬盘上」的文件,所以一定要让 Git 忽略它。做法是在项目的 .gitignore(告诉 Git 哪些文件不要追踪的清单)里加一行:
.env
这里有一个 Git 官方文档写明、但很多人不知道的细节:.gitignore 对已经被追踪的文件无效。如果你在加进 .gitignore 之前就已经提交(commit,把文件目前的内容存成 Git 的一笔纪录)过 .env,它会继续被追踪。所以要在第一次提交之前就设好,并用下面这个指令确认 Git 真的忽略了它。指令印出 .env,代表它已被忽略;什么都没印,代表没有被忽略,或它早就被追踪了:
git check-ignore .env
Git 的基本观念(保存库、commit 也就是一次提交纪录、为什么「删掉文件」不等于「从历史消失」),请看 给 AI 用户的 Git 入门。
环境变量也不是保险箱
环境变量解决的是「密钥跟着代码外流」的问题,不是加密。用你的账号运行的程序,通常都读得到你的环境变量;Claude Code 的沙箱文档也明确写出,沙箱里运行的指令预设会继承环境变量,包括其中的秘密。所以下一节的几道防线一样重要。
再多三道防线:分开密钥、用量上限、定期轮替
这三点出自 Anthropic 与 OWASP(一个专注于软件安全的开放社交媒体)的建议,原则上适用于各家服务;具体设置位置请以你使用的服务为准。
- 依用途分开密钥:开发、测试、正式环境各用一把;不同的项目、不同的工具也各用一把。其中一把外泄时,只禁用那一把,其他用途不受影响。这也是 最小权限原则 的应用:OWASP 指出,创建秘密时就应该只给它完成用途所需的最少权限。
- 设置用量或花费上限:Anthropic 的说明指出,上限能在密钥外泄或程序出错时,防止意外的大量用量。它不能防止外泄,但能限制外泄的损失。
- 定期轮替:密钥轮替(Key rotation)是定期创建新密钥、换到使用的地方,再禁用旧密钥。OWASP 的理由是:轮替让被偷走的凭证只在短时间内有效。
最后,可以让工具帮你把关。秘密扫描(Secret scanning)是自动在代码与 Git 历史中寻找密钥、密码等秘密的机制。以 GitHub 为例,它会扫描保存库所有分支的完整 Git 历史;它的推送保护(Push protection)更进一步:推送(push)是把你电脑上的提交上传到远程保存库,推送保护会在含有秘密的推送到达保存库之前就挡下来。Anthropic 也说明,它参与了 GitHub 的秘密扫描合作:在公开保存库里被发现的 Anthropic 密钥,会被自动禁用并通知用户。
不过,这类合作只涵盖特定的服务商与情境,不要把它当成唯一的保护。
密钥外泄时的处理步骤
下面的顺序是本站依 OWASP 的事件处置建议与 GitHub 文档整理的,不是官方标准。关键只有一句:先让它失效,再处理其他事情。
- 立刻撤销那把密钥:到服务商的后台禁用或删除它。这是唯一能确定「别人拿到也不能用」的方法,所以排第一,不要等查清楚原因再做。
- 创建新密钥,换到原本使用的地方:更新环境变量或秘密保存,确认你的程序恢复正常。
- 检查用量与纪录:看外泄期间有没有你不认得的用量。费用有异常时,联系服务商。
- 清理外泄的位置:删掉那则留言、那张截屏、那段对话。如果密钥被提交到 Git,GitHub 的文档说明:密钥撤销或轮替之后就无法再使用,这样可能就已足够;改写 Git 历史需要协调所有拷贝过保存库的人,而且已经被拷贝(fork 或 clone)的副本你无法清除。
- 找出原因,补上防线:是忘了
.gitignore?是截屏没检查?把对应的预防做法补上,并考虑打开秘密扫描。
常见的错误是反过来做:先急着把 commit 删掉、把保存库改成私人,却没有撤销密钥。GitHub 的文档特别提醒,提交过的秘密在从最新版本移除后,仍然存在于 Git 历史里;只删文件,密钥其实还能用。
一张表整理
| 你想做的事 | 建议做法 |
|---|---|
| 让程序使用密钥 | 从环境变量读取,代码里不写密钥 |
| 在自己的电脑上开发 | 用 .env,第一次提交前加进 .gitignore 并确认 |
| 给 AI 代理使用 | 密钥不放在它能读的文件夹里,或设置禁止读取 |
| 网页要调用 AI 服务 | 由你的服务器调用,浏览器端不放密钥 |
| 多个项目、多个人 | 各用各的密钥 |
| 避免账单失控 | 设置用量或花费上限,定期看用量 |
| 怀疑外泄 | 先撤销,再换新、查用量、清理 |
接着看什么
- 环境变量、路径怎么设置:终端机基础
- 为什么删掉 commit 不等于删掉历史:给 AI 用户的 Git 入门
- 实际送出第一个请求:第一次调用 LLM API
- 让 AI 代理碰你的电脑之前:让 AI 代理安全操作电脑
- 名词不熟:到 名词小辞典 查,例如 API 密钥、环境变量、.env 档、.gitignore、秘密扫描、密钥轮替。
常见问题
API Key 和密码有什么不同?
密码是你登录账号时输入的;API Key 是给程序用的,会附在每一次请求里,让服务直接认定请求来自你的账号。也因为它是给程序用的,你可以替不同用途各建一把,出事时只禁用那一把,不必动到账号密码。
API Key 外泄会怎样?
拿到密钥的人可以用你的账号调用服务,费用算在你头上,Anthropic 的官方说明就把它比喻成信用卡号。视服务而定,对方也可能读到或改动这把密钥权限范围内的数据。
不小心把密钥提交到 Git,删掉那个 commit 就好了吗?
不够。GitHub 的文档说明,提交过的秘密会留在 Git 历史里,也可能已经跟着分支、被拷贝的保存库或自动化流程的纪录扩散出去。正确顺序是先撤销并换新密钥,旧密钥失效后,留在历史里的那串字也就不能用了。
可以把密钥贴给 AI,请它帮我调试吗?
不建议。贴进对话的文字会成为对话纪录的一部分,等于多了一个可能外泄的地方;AI 帮你调试通常只需要知道「有没有设置这个环境变量」,不需要看到密钥本身。如果已经贴了,就把那把密钥当作外泄处理。
把密钥放在环境变量里就绝对安全吗?
不是绝对。环境变量的好处是密钥不会跟着代码被提交,但用你的账号运行的程序,包括它启动的子程序,通常都读得到;Claude Code 的文档也指出,沙箱里的指令预设会继承这些环境变量。所以仍然要搭配分开密钥、用量上限与定期轮替。
密钥多久要换一次?
没有一体适用的答案。OWASP 建议定期轮替,让被偷走的密钥只在短时间内有效;Anthropic 的建议以每 90 天为例。比定期更重要的是:只要怀疑外泄,就立刻换。
留言
用 GitHub 账号登录就能留言,留言会公开显示在 GitHub Discussions。留言前请先看社区规则。