很多人拿到密钥第一件事就是粘进代码跑通,跑通之后它就一直在那儿了。等到发现账单异常、或者要把代码推到公开仓库,才开始想「这玩意儿该放哪」。这篇不讲怎么申请,只讲拿到之后怎么放、怎么用、怎么在出事前拦住,以及真的漏了按什么顺序收场。
很多人拿到密钥第一件事就是粘进代码跑通,跑通之后它就一直在那儿了。等到发现账单异常,或者要把代码推到公开仓库,才开始想这东西该放哪。这篇不讲怎么申请,只讲拿到之后怎么放、怎么用、怎么在出事前拦住,以及真的漏了按什么顺序收场。
核心判断只有一个:这把密钥能被谁看到,就等于谁能花你的钱。所以别去背什么最佳实践,先问自己三件事——它现在存在几个地方、这些地方谁能读到、如果明天被别人拿到我多久能发现。这三问答清楚了,放法自然就定了。
密钥到底能放哪:几种放法的取舍
本地开发最省事的做法是放 .env 或者系统环境变量,代码里只读变量名。关键在于写完 .env 之后别急着提交,先确认忽略规则真的生效:用 git status 看一眼,待提交列表里不该出现这个文件。很多泄露不是因为没写忽略,而是写之前已经提交过一次,后面加了规则也盖不住历史记录。
| 放法 | 适合场景 | 主要风险 |
|---|---|---|
| 本地 .env / 环境变量 | 单人开发、调试 | 临时改代码时容易被顺手写死 |
| 部署平台的密钥变量 | 长期跑在服务端 | 配错环境会泄漏到不该跑的进程 |
| 密钥管理服务 | 多人协作、多服务 | 接入成本高,小项目反而绕 |
| 直接写在代码或配置里 | 只有一次性脚本 | 一旦提交或打包就基本收不回来 |
| 共享一把给全团队 | 临时应急 | 出事定位不到人,只能整体作废 |
- 团队协作别发共享密钥,一人一把单独发,出问题能定位到人,也能只吊销一个人的
- 服务端长期运行放密钥管理服务或部署平台的密钥变量,别写进镜像和 CI 配置文件
- 一次性脚本就直接在终端会话里输入,用完关掉,没必要上任何管理工具
- 任何放法都要先确认「谁能读到」,只读得到自己机器的才算安全下限
最常见的几条泄露路径,提前堵住
泄露很少是被人攻破的,多半是自己送出去的。最常见的三种:写进前端代码让浏览器直连,等于把密钥印在传单上发;贴进聊天记录、工单、截图或者 AI 对话窗口,发出去那一刻就得当成明文;打进客户端安装包、Docker 镜像或者留在 Git 历史里,删文件不等于删记录。
- 前端直连
- 密钥会出现在浏览器请求里,任何人打开开发者工具都能看到,正确做法是走自己的服务端转发
- 日志与报错
- 确认请求头不会被整体打印出来,排查问题时先看日志里有没有带 key 的整行
- Git 历史
- 删掉文件再加忽略规则,旧提交里仍能翻出来,要按彻底清除处理
- 截图与工单
- 截图、录屏、报错贴图都算明文外发,发之前先想清楚要不要顺手换一把
- 搜一遍仓库在项目里全文搜索密钥的特征片段,包括历史提交,确认没有残留。
- 看一眼日志输出手动触发一次报错,检查打印出来的内容里有没有完整的请求头或配置对象。
- 查打包产物客户端、镜像、构建产物里搜同样片段,确认没有被打进去。
- 确认外发记录回想这周有没有把密钥贴给谁、发到哪个群里,有就当已泄露处理。
拿到密钥先做三件事再上项目
新手爱把「能跑通」和「业务逻辑对」混在一起排查,结果一个报错查半天。正确顺序是先确认鉴权通,再看别的。发一个最小请求,只看返回是不是鉴权类错误,是的话去查密钥本身,不是的话再往下查业务。
- 先用最小请求确认能通,别把连通性和业务逻辑混在一起排查,报错分类可对照站内 /ai-dict 与报错类文章
- 到 /official-api/providers/openai 核对当前计费口径与限速说明,避免把限流当成密钥失效
- 给自己设一个用量提醒或额度上限,异常调用最早是从账单上发现的,不是从代码里
- 到 /tools/speed-test 量一次延迟基线,之后变慢时能分清是网络还是鉴权问题
限流和密钥失效经常被搞混。表现都是请求失败,但处理方式完全不同:前者等一会儿或者提额度,后者只能换密钥。所以排查时先看一眼错误类型,别一失败就以为密钥废了,也别反过来一直等限流,结果是密钥早被人换了。
怀疑泄露之后的处理顺序
顺序比动作重要。很多人第一反应是查谁泄的,翻聊天记录、翻提交人,一天过去密钥还在被人用着。正确顺序是先把它废掉,后面所有调查才有意义——旧密钥一作废,陌生调用自然就停了,你也能安心去查原因。
- 先吊销重建旧密钥立刻作废,新建一把。别评估影响再决定,评估的时候损失还在涨。
- 翻用量与调用日志确认有没有陌生来源的调用、集中在什么时间段、调用了哪些接口,判断是试探还是大规模使用。
- 排查所有写过密钥的地方仓库历史、镜像、CI 变量、共享文档、本地脚本、其他同事机器,一处一处过。
- 最后补流程把密钥改成只从环境读、加提交前扫描、停掉共享密钥的使用习惯,再回头复盘这次是谁在什么环节放出去的。
补流程的重点不是加多少工具,而是让「密钥只能从环境读」变成默认写法。团队里只要有一个人图省事把密钥写死在代码里,其他人的规范都白搭。提交前扫描这类手段的意义就在这,它拦的是习惯,不是恶意。
| 阶段 | 先做什么 | 别做什么 |
|---|---|---|
| 发现异常用量 | 立即吊销重建 | 先去追责或评估影响 |
| 确认泄露范围 | 翻调用日志找来源和时间 | 只删掉本地那个文件就以为完事 |
| 后续收尾 | 检查历史、镜像、CI 变量 | 换完新密钥就当没发生过 |
| 长期防护 | 统一从环境变量读密钥 | 继续团队共享一把密钥 |
常见问题
密钥能不能直接写在前端代码里?
不能。前端代码会下发到用户浏览器,等于把密钥公开给所有人。正确做法是自己搭一层服务端做转发,前端只调自己的接口。如果只是本地临时验证,也别提交到仓库,验完就删。
多人共用一个密钥是不是省事?
短期省事,长期是麻烦。共用的结果是出问题时定位不到人、也没法只吊销某一个人的权限。团队里建议一人一把,按人发、按人停,出问题只影响一条线。小团队两三个人的话,至少做到每台机器一本账。
怎么判断密钥是被盗用还是自己跑超了?
看调用来源和时间分布。自己跑的任务通常有固定节奏、固定模型和调用方;被盗用往往是陌生模型、集中在某几个时段、请求形态也不像你的业务。先去后台翻用量明细,对不上再按泄露流程走吊销重建。