API Key 不应该放在 shell 配置文件里。这是很多开发者都有的习惯,图省事,但风险被长期低估。
最近一次操作失误让我意识到这个问题:一条命令找不到目标文件,fallback 执行了 env,把整个终端环境变量打印出来,十几个 API key 直接进了 AI 对话的上下文,不得不全部轮替。
事故很小,但揭示了一个结构性问题:把 key 放在 shell 配置文件里,意味着它们始终暴露在所有子进程、所有工具的视野里。
为什么 shell 配置文件不适合存 API key
不同的 shell 有不同的配置文件,但都面临同样的问题:
- zsh:
~/.zshrc、~/.zprofile - bash:
~/.bashrc、~/.bash_profile、~/.profile - fish:
~/.config/fish/config.fish
在这些文件里写 export API_KEY=xxx,后果是:
- 每个终端会话启动就自动加载,任何子进程都能读到
env、printenv等命令随时能看到明文- AI 工具、日志收集、调试输出都可能意外捕获
- 一旦配置文件被同步到 dotfiles 仓库,直接公开
根本问题是:key 的生命周期远长于它实际被用到的时间。
更好的方式
方案一:项目级 .env + 精确注入
最轻量的改进。每个项目只放自己用到的 key,通过脚本精确提取,不污染全局环境。
run.sh 示例:
优点:简单,无依赖,适用于所有操作系统。
缺点:key 仍然明文存在磁盘。
方案二:macOS Keychain
系统级加密存储。key 加密保存在 Keychain 里,只在被读取的瞬间解密到内存,cat、grep、env 全都看不到。
存入:
在脚本里读取:
使用体验: 开机登录 Mac 时系统 Keychain 自动解锁,整个会话期间脚本可以直接读取,不需要输密码。第一次访问某个条目时系统会弹一次授权框,点"始终允许"后就再也不会弹了。
这是替代 shell 配置文件存 key 的最直接方案,对工作流几乎没有影响。macOS 独有,Linux 和 Windows 有各自的等效方案(secret-tool、Windows Credential Manager)。
方案三:Bitwarden CLI(私有部署)
如果你有 Bitwarden 实例(包括私有部署的 Vaultwarden),可以用官方 CLI bw 在脚本里动态拉取 key。
配置私有部署地址:
登录并获取 session:
Session 在当前终端会话内有效,关闭终端后失效,不会持久暴露。
在脚本里读取指定条目:
bw get password 按条目名称检索,返回该条目的 password 字段。也可以用 bw get notes 获取备注字段,适合存储格式复杂的 key。
适合的场景: 多台设备共用同一套 key,或者需要跨平台(macOS/Linux/Windows 都支持)。key 集中在 Bitwarden 管理,换设备只需重新登录,不用手动迁移 .env 文件。
迁移建议
如果你现在 shell 配置文件里有大量 export KEY=xxx:
- 按项目整理,每个项目建一个
.env,只放该项目用到的 key - 高价值凭证(数据库密码、支付相关)迁移到 Keychain 或 Bitwarden
- 把 shell 配置文件里的
export KEY=全部删掉 - 确认
.env文件加入了.gitignore
不需要一次做完。先把最敏感的几个迁走,剩下的项目用到哪个迁哪个。
总结
| 方案 | 明文落盘 | 跨平台 | 跨设备 | 依赖 |
|---|---|---|---|---|
| shell 配置文件 | ✓(危险) | ✓ | 需手动同步 | 无 |
| 项目 .env | ✓ | ✓ | 需手动同步 | 无 |
| macOS Keychain | ✗ | ✗ | ✗ | 系统内置 |
| Bitwarden CLI | ✗ | ✓ | ✓ | bw CLI |
没有完美方案,但任何一个都比 shell 配置文件好。最实用的起点是:**清空配置文件里的 key,改用项目级 ****.env**,高价值凭证再逐步迁到 Keychain 或 Bitwarden。
作者: TorchTree
原文地址: https://torchtree.com/post/api-key-storage-best-practices/
发布时间: 2026-04-07
版权声明: CC BY-NC-SA 4.0