用 Go 写了一个极简 API Key 管理工具,两个字母搞定一切
日常开发中,我们每个人手里都有十几个甚至几十个 API Key:OpenAI、Anthropic、AWS、GitHub Token、Stripe……项目里的.env文件~/.bashrc或~/.zshrc里的环境变量浏览器书签或备忘录各种配置文件用的时候到处翻,找到了还要手动复制。更糟糕的是,.env文件一不小心就提交到 Git 了,Key 泄露到 GitHub 上……所以我写了—— 一个极简的终
前言
日常开发中,我们每个人手里都有十几个甚至几十个 API Key:OpenAI、Anthropic、AWS、GitHub Token、Stripe……
它们通常散落在这些地方:
- 项目里的
.env文件 ~/.bashrc或~/.zshrc里的环境变量- 浏览器书签或备忘录
- 各种配置文件
用的时候到处翻,找到了还要手动复制。更糟糕的是,.env 文件一不小心就提交到 Git 了,Key 泄露到 GitHub 上……
所以我写了 mk (My Keys) —— 一个极简的终端工具,把所有 API Key 存到系统 Keychain 里,两个字母就能管理。
效果演示
$ mk set openai sk-proj-abc123...
✓ Set openai
$ mk set nvidia nvapi-xyz789...
✓ Set nvidia
$ mk ls
● nvidia
● openai
$ mk get openai
sk-proj-abc123...
$ mk cp openai
✓ Copied openai to clipboard
$ mk rm openai
✓ Removed openai
为什么不用 .env?
我对比了一下常见的方案:
| 方案 | 安全性 | 便捷性 | 跨项目 |
|---|---|---|---|
.env 文件 |
❌ 明文存磁盘 | ⚠️ 需要 cd 到项目目录 | ❌ 每个项目都要配 |
| 1Password | ✅ 加密存储 | ⚠️ 需要打开 App | ✅ 全局可用 |
pass (GPG) |
✅ 加密存储 | ❌ 需要 GPG 配置 | ✅ 全局可用 |
| mk | ✅ 系统级加密 | ✅ 两个字母 | ✅ 全局可用 |
mk 的优势在于:零配置,零依赖,跟系统登录密码同级安全。
实际使用场景
1. 嵌入命令
curl -H "Authorization: Bearer $(mk get openai)" https://api.openai.com/v1/models
2. 设置环境变量
export ANTHROPIC_API_KEY=$(mk get anthropic)
3. 复制到剪贴板(终端不留痕迹)
mk cp openai
这个特别实用。直接 mk get 会在终端里打印 Key,而 mk cp 只复制到剪贴板,终端历史里不会留下任何痕迹。
安装
macOS
brew tap axliupore/tap
brew install axliupore/tap/mk
Linux
从 GitHub Releases 下载安装包:
# Debian / Ubuntu
sudo dpkg -i mk_*_linux_amd64.deb
# Fedora / RHEL
sudo rpm -i mk_*_linux_amd64.rpm
# Alpine
sudo apk add --allow-untrusted mk_*_linux_amd64.apk
Windows
scoop bucket add axliupore https://github.com/axliupore/scoop-bucket
scoop install mk
从源码编译
go install github.com/axliupore/mk@latest
技术实现
整体架构
mk/
├── main.go # 入口
├── cmd/ # Cobra 命令
│ ├── root.go
│ ├── set.go
│ ├── get.go
│ ├── cp.go
│ ├── ls.go
│ └── rm.go
├── internal/ # 内部包
│ ├── keyring.go # go-keyring 封装
│ ├── style.go # lipgloss 终端美化
│ ├── list_darwin.go # macOS ls 实现
│ ├── list_linux.go # Linux ls 实现
│ └── list_windows.go # Windows ls 实现
├── go.mod
└── .goreleaser.yaml # 跨平台构建配置
技术栈
- Go 1.26 — 单二进制,零依赖
- Cobra — CLI 框架
- go-keyring — 跨平台 Keychain 访问
- lipgloss — 终端输出美化(charmbracelet 出品)
- GoReleaser — 跨平台自动构建发布
核心难点:实现 mk ls
go-keyring 库只提供了 Set、Get、Delete 三个 API,没有 List。所以我需要自己解析各平台的原生命令输出来实现列表功能。
macOS:解析 security dump-keychain
这是最复杂的一个。security dump-keychain 的输出格式非常不一致:
属性标签有三种写法:
"svce"<blob>="mk" # 带引号
svce<blob>="mk" # 不带引号
0x00000007 <blob>="mk" # 十六进制代码
更坑的是,当属性值包含非 ASCII 字符(比如中文别名 刘)时,值会被十六进制编码:
0x00000008 <blob>=0xE58898E58898...
而不是正常的 UTF-8:
0x00000008 <blob>="刘"
我写了 6 种模式匹配器来覆盖所有组合,加上 encoding/hex 解码十六进制的 blob 值。
Windows:cmdkey /list 的多语言问题
在中文 Windows 上,cmdkey /list 的输出是这样的:
目标: LegacyGeneric:target=mk:openai
而不是英文的:
Target: LegacyGeneric:target=mk:openai
一开始我加了中英文两种匹配,但后来想到日文、韩文怎么办?最终方案是匹配 LegacyGeneric:target=mk: 这个内部标识符——它在任何语言系统下都是英文的。
Linux:secret-tool search
这个反而是最简单的。secret-tool search --all service mk 输出很干净。唯一要注意的是,没有匹配项时返回退出码 1,需要单独处理。
管道兼容性
mk get 的输出是纯文本,不带任何 ANSI 颜色代码。这是刻意的设计,确保 $(mk get alias) 在脚本中直接可用,不需要额外处理。
而 mk ls、mk set 等命令的输出则用 lipgloss 做了美化,有颜色和图标。
跨平台构建
用 GoReleaser 统一构建 macOS、Linux、Windows 三个平台的二进制。一开始踩了个坑:以为 Linux 上 go-keyring 依赖 dbus 需要 CGO_ENABLED=1,结果交叉编译时各种报错。后来发现 godbus/dbus 是纯 Go 实现,CGO_ENABLED=0 就够了。
安全性
- Key 存储在操作系统原生的加密凭据库中(macOS Keychain / Windows Credential Manager / Linux Secret Service)
- mk 不会往磁盘写任何文件
- 不联网,不上传,完全离线
mk cp直接复制到剪贴板,终端里不打印- MIT 开源,代码可审计
总结
如果你也经常为管理 API Key 发愁,可以试试 mk。两个字母,从此安心。
- GitHub: https://github.com/axliupore/mk
- 开源协议: MIT
觉得有用的话,欢迎 Star ⭐
更多推荐


所有评论(0)