我的 API Key 散在 7 个 .env 里,试了三种方案才收拢
先说结论:我把 7 个项目的 API Key 从各自散落的 .env 里收拢到了一个地方,方法是起一个只写不读的密钥服务。下面是我试错的过程,包括两条走不通的路。
起因
整理硬盘时数了一下,7 个 .env 文件,12 个不同服务的密钥。Stripe、OpenAI、GitHub、两个云厂商、一个短信服务、一个地图 API,还有几个我已经忘了是干什么的。
其中有个项目 .gitignore 里只写了 .env,没写 .env.local,那个文件就差一次 commit。这种险我大概冒了一年多。
问题不只是泄露风险。改一个密钥要翻五个目录,改漏一个,那个项目半夜就开始报 401。换台机器要重配一遍,因为 .env 不在仓库里,得从别的地方找回全部 12 个。同事问"那个 key 是啥",只能截图发微信。
试过但不推荐的两条路
方案一:全部塞进系统环境变量
听起来最省事。写进 ~/.zshrc 或者 Windows 的系统环境变量,之后所有项目直接读。
死的很直接:改一个要改配置文件再 source 一遍,IDE 里的终端经常不跟着刷新,改了半小时代码还在用旧值。而且换机器的时候,12 个 key 还是得手工搬过去——它只是把 .env 移了个位置,没解决核心问题。
方案二:加密后提交进仓库
用 git-crypt 或者 openssl 把 .env 加密,密文提交,本地解密。
死在一个死循环上:解密的密钥本身存哪?存本地还是等于没加密;存 CI 的 secrets 里,那又回到"密钥散在各平台"的老问题。而且团队新人的入职流程会变成"先教你配加密环境",比配 .env 还麻烦。
最后采用的做法
起一个小的密钥服务,所有密钥存在里面,项目代码不改——照常从环境变量读值,值在运行时由服务注入。
具体用的是 GitHub 上的 treg(tools-registry),Python 写的。选它不是因为功能多,是因为它的设计思路跟我要的一致。装 CLI 就一个包:
pip install tools-registry
注意这只有命令行工具,想自己跑服务端还得装扩展,后面会踩这个坑。
存密钥:
treg secret add STRIPE_KEY --value sk_live_xxx
文件类凭据(比如 GCP 的 service account json)走另一条:
treg secret add GCP_SA --file ./sa.json --kind secret_file
看有哪些(只列名字和类型,看不到值):
treg secret ls
我认为重要的三条原则
工具能换,这三条我觉得不能松。
一、存进去的密钥不该取得回来。
treg 的接口设计成只写不读——你存了 sk_live_xxx,之后任何 API 调用都拿不回原文,只能用不能看。这不是技术做不到,是故意不给。
理由很实在:后端被拖库的时候,加密过的密文比明文值钱得多。而且"取不回来"这个约束会强迫你在创建密钥的时候就登记清楚用途,而不是随手贴进某个文件里。
二、密钥要注入,不要暴露。
它注入的方式是在起子进程时塞进环境,父进程的环境里没有。核心就一行:
env.update(secret_env) # 按存储时的名字注入子进程
这样即使项目里某个第三方依赖想读环境变量,它也只能读到被授权的那几个,而不是全家桶。
三、名字匹配得有确定规则。
这条是我用下来最意外的收获。它导入 .env 时不是按名字死死对齐,而是把变量名按下划线切开去比对,比如 TREG_RESEND_API_KEY 会去匹配 RESEND。关键是取最长匹配:同时存在 HF 和 HUGGINGFACE 时,HUGGINGFACE_API_KEY 必须命中长的那个。
没有这条规则,短 token 会抢走本该属于长 token 的密钥,绑到错的凭据上,而且报错信息通常只会告诉你"认证失败",很难查到根因。
踩到的三个坑
装错包。前面提过,pip install tools-registry 只装 CLI。想自己跑服务端要加 [server],否则会连不上服务。我在这上面浪费了二十分钟。
以为存完就能直接用。实际上 add 只是把值存进去,还得建一个绑定关系,告诉它"这个密钥给哪个 API 用、放哪个 header 里"。我第一次存完直接调用,报找不到绑定,愣了挺久。
--kind 选错。json 文件必须标成 secret_file。用默认的 env 会把它当成一整串字符串塞进环境变量,项目里读出来全是转义符,报的错还特别迷惑。
自建服务端的命令
团队共用就起一个服务,大家连同一个,密钥只落在服务器上。两条命令:
uv run python -m treg keygen # 生成加密用的密钥,只用一次
uv run python -m treg # 起服务,默认 0.0.0.0:18790
什么场景够用,什么场景不够
说实话它不算严肃的生产级方案。没有细粒度权限控制,没有审计日志,没有自动轮换,也没有高可用。真要给几十人的团队用,Vault 或者云厂商的 KMS 才是正解。
但对我这种一个人维护几个项目、偶尔两三个人协作的场景,它把最要命的那件事解决了:密钥不再散落在磁盘各个角落,也不会跟着一次手滑的 commit 跑出去。
12 个密钥收拢到一处之后,我至少能一眼看清自己有哪些凭据、分别用在哪。这件事本身比工具选得对不对更重要。
- 点赞
- 收藏
- 关注作者
评论(0)