kcenv 是一个跨平台轻量环境变量秘钥管理脚本。
它适合把 OPENAI_API_KEY、ANTHROPIC_API_KEY、REDMINE_API_KEY 这类本机秘钥从 shell 配置文件中移出,统一存到系统秘钥环,再按需导出给 fish、sh、脚本或 CLI agent 使用。
- macOS:使用 Keychain(
security命令) - Linux:使用 Freedesktop Secret Service(
secret-tool命令,通常由 gnome-keyring 或 KWallet 提供)
- macOS 使用原生
security命令;Linux 使用secret-tool,无 Python/Node 等额外运行时。 - 所有条目固定存放在 service:
kcenv、account:NAME。 - 内部索引 account:
__KCENV_KEYS__,只保存变量名列表。 - 不扫描全局秘钥库,不读取其他 app 的秘钥数据。
- 支持
fish和 POSIXsh导出格式。 - 变量值不会写入仓库或 shell 配置文件。
kcenv 使用统一的命名空间:
service = kcenv
account = __KCENV_KEYS__ # 内部索引,只保存变量名列表
account = OPENAI_API_KEY # 真实秘钥值
account = REDMINE_API_KEY # 真实秘钥值
kcenv list 和 kcenv export 只读取 __KCENV_KEYS__ 中登记过的变量名,然后逐个精确读取:
# macOS
security find-generic-password -s kcenv -a NAME -w
# Linux
secret-tool lookup service kcenv account NAME它不会执行全局秘钥库 dump,也不会枚举其他 service。
macOS:系统自带 security,无需额外安装。
Linux:安装 secret-tool(桌面版通常已有 gnome-keyring 或 KWallet 后台,只需补 CLI):
# Debian / Ubuntu
sudo apt install libsecret-tools
# Fedora
sudo dnf install libsecret-tools
# Arch Linux(secret-tool 包含在 libsecret 包中)
sudo pacman -S libsecret复制脚本到 PATH:
mkdir -p ~/.local/bin
cp bin/kcenv ~/.local/bin/kcenv
chmod 700 ~/.local/bin/kcenv确认可用:
kcenv --help创建 ~/.config/fish/conf.d/kcenv.fish:
if status is-interactive
set -l kcenv_bin $HOME/.local/bin/kcenv
if test -x $kcenv_bin
$kcenv_bin export --fish | source
end
end新开一个交互式 fish 后,kcenv 管理的变量会自动注入当前 shell。
写入变量:
kcenv set OPENAI_API_KEY也可以直接把值作为第二个参数传入(会出现在进程列表中,敏感场景优先用 stdin):
kcenv set DEEPSEEK_API_KEY sk-...也可以从 stdin 写入,适合迁移脚本:
printf '%s\n' "$OPENAI_API_KEY" | kcenv set OPENAI_API_KEY读取变量:
kcenv get OPENAI_API_KEY列出已登记变量名:
kcenv list删除变量:
kcenv delete OPENAI_API_KEY导出给 fish:
kcenv export --fish | source导出给 POSIX sh/bash/zsh:
eval "$(kcenv export --sh)"推荐在当前 shell 中显式加载后再启动目标命令:
kcenv export --fish | source
codexPOSIX sh/bash/zsh 可以使用:
eval "$(kcenv export --sh)"
your-command如果只想给一个命令临时注入,可以启动一个子 shell:
sh -c 'eval "$(kcenv export --sh)"; exec "$@"' -- your-command arg1 arg2AI Agent 通常有两种读取方式:继承启动环境,或 在任务中显式调用 kcenv。
这是最推荐的方式。先在 shell 中加载 kcenv,再启动 agent:
kcenv export --fish | source
codex也可以启动其他 CLI agent:
kcenv export --fish | source
claudekcenv export --fish | source
pi这样 agent 进程能直接通过标准环境变量读取:
printf '%s\n' "$OPENAI_API_KEY"agent 内部运行的测试、脚本、子进程也会继承这些环境变量。
如果不想让当前 shell 常驻这些变量,可以只给单次 agent 启动注入:
sh -c 'eval "$(kcenv export --sh)"; exec codex'带参数时:
sh -c 'eval "$(kcenv export --sh)"; exec "$@"' -- codex --model gpt-5.1在自动化脚本或 agent 任务中,也可以直接读取某个变量:
export OPENAI_API_KEY="$(kcenv get OPENAI_API_KEY)"这种方式适合只加载少数 key,但要注意:能执行 shell 命令的 agent 也能调用 kcenv get NAME 读取对应秘钥。
| Agent | 推荐方式 | 说明 |
|---|---|---|
| Codex CLI | env 注入;或 codex login --with-api-key |
~/.codex/auth.json 是登录缓存,不建议当动态模板 |
| Claude Code | apiKeyHelper;或 env 注入 |
apiKeyHelper 可以直接调用 kcenv get |
| pi | models.json 的 !command;或 env 注入 |
apiKey 支持 $ENV_VAR 和 !command |
| OpenCode | env 注入;或 wrapper 生成 auth.json |
官方主要使用 /connect 写 ~/.local/share/opencode/auth.json |
Codex CLI 可以继承启动环境:
kcenv export --fish | source
codexAPI key 登录可以从 stdin 读取:
kcenv get OPENAI_API_KEY | codex login --with-api-key非交互 codex exec 可以用 CODEX_API_KEY 做单次运行:
CODEX_API_KEY="$(kcenv get OPENAI_API_KEY)" codex exec "summarize this repo"如果你配置了自定义 provider,Codex 的 provider key 通常通过 config.toml 里的 env_key 指定变量名;此时先用 kcenv export 注入对应环境变量即可。~/.codex/auth.json 是 Codex 的登录缓存或凭据存储位置,不建议手写成动态模板。
Claude Code 可以直接继承环境变量:
kcenv export --fish | source
claude更适合 kcenv 的方式是使用 apiKeyHelper。在 ~/.claude/settings.json 中配置:
{
"apiKeyHelper": "kcenv get ANTHROPIC_API_KEY"
}apiKeyHelper 会由 /bin/sh 执行,stdout 作为认证值。这样不需要把 API key 写入 ~/.claude.json 或 shell 配置文件。Claude 的 --bare 模式也支持 ANTHROPIC_API_KEY 或 apiKeyHelper。
pi 支持环境变量、~/.pi/agent/auth.json 和 ~/.pi/agent/models.json。
普通启动可以继承环境:
kcenv export --fish | source
pi一次性传入 key:
pi --provider anthropic --api-key "$(kcenv get ANTHROPIC_API_KEY)"自定义 provider 推荐在 ~/.pi/agent/models.json 使用 !command:
{
"providers": {
"openrouter": {
"apiKey": "!kcenv get OPENROUTER_API_KEY"
}
}
}也可以使用环境变量引用:
{
"providers": {
"openrouter": {
"apiKey": "$OPENROUTER_API_KEY"
}
}
}pi 的 API key 解析优先级是:运行时覆盖、auth.json、环境变量、自定义 provider fallback。models.json 的 apiKey 和 headers 支持 $ENV_VAR、${ENV_VAR}、!command 和字面量。
OpenCode 可以继承环境变量:
kcenv export --fish | source
opencodeOpenCode 官方推荐通过 TUI 的 /connect 添加 provider key,并写入:
~/.local/share/opencode/auth.json
如果要用 kcenv 管理这个文件,可以用 wrapper 在启动前生成或更新 auth.json,并设置 0600 权限。不同 provider 的 JSON 字段可能变化,建议先用 /connect 生成一次文件,再把其中的明文值替换为 wrapper 注入。
OpenCode 还支持这些配置入口:
~/.config/opencode/opencode.json
OPENCODE_CONFIG
OPENCODE_CONFIG_CONTENT
OPENCODE_CONFIG_DIR
截至本仓库调研时,未确认 OpenCode 的 provider credential 字段是否支持 $ENV_VAR 或 !command 插值;因此文档中只推荐 env 注入或 wrapper 生成 auth.json 这两种保守方案。
如果你安装了 ~/.config/fish/conf.d/kcenv.fish,交互式 fish 会自动加载 kcenv:
codex但非交互命令不会自动加载,例如:
fish -c 'codex'因为 hook 通常写在 if status is-interactive 里。非交互场景需要显式 source:
fish -c 'kcenv export --fish | source; codex'- 只把当前任务需要的 key 放进
kcenv或注入给 agent。 - 不要把生产数据库、生产服务器、高权限云账号 token 默认注入所有 agent。
- agent 可以读取自己的环境变量,也可以运行
env;因此不要把“不希望 agent 看到的秘钥”注入它的进程。 kcenv list只显示变量名,但变量名本身也可能透露服务信息;需要时避免在日志中输出。
仓库包含一个 Codex/pi/agent 可用的 skill:
skills/kcenv/SKILL.md
安装到本机 agent skill 目录:
mkdir -p ~/.agents/skills/kcenv
cp skills/kcenv/SKILL.md ~/.agents/skills/kcenv/SKILL.md该 skill 约束 agent 在处理 kcenv、秘钥环 env、env.fish 迁移时:
- 不打印明文秘钥。
- 只操作
kcenv命名空间。 - 不扫描全局秘钥库。
- 修改前先说明影响范围。
- 写入后用长度/哈希/一致性检查验证。
如果 hook 写在 if status is-interactive 中,非交互 fish -c 不会自动加载变量。这是预期行为。
需要时显式加载:
fish -c 'kcenv export --fish | source; your-command'首次读取某个条目时,macOS 可能要求允许 Terminal/iTerm/Warp 访问 Keychain。允许后一般会缓存。
安装 libsecret-tools(见上方安装说明)。Arch 用户安装 libsecret 即可。
桌面登录后 gnome-keyring 或 KWallet 通常会自动解锁。如果 SSH、无头环境或后台任务读取失败,可能是 Secret Service 未运行或 keyring 处于锁定状态。
无桌面会话时可手动启动:
eval "$(dbus-run-session -- sh -c 'gnome-keyring-daemon --unlock --components=secrets')"KDE 用户可在系统设置中确认已启用 KWallet 的 Secret Service 接口。
SSH、launchd/systemd 服务、CI、后台进程可能没有已解锁的秘钥环会话。此时需要调整运行环境,或改用专门的 secret manager。kcenv 不适合无 keyring 的容器/CI 环境。
macOS 与 Linux 的秘钥库不共享。如需迁移,在目标机器上逐个导入:
# 在源机器导出变量名,在目标机器逐个 set
for name in $(kcenv list); do
printf '%s' "$(kcenv get "$name")" | kcenv set "$name"
done不要用这些命令实现 list/export:
# macOS
security dump-keychain
security find-generic-password -g
# Linux
secret-tool search --allkcenv 的设计目标是只精确读写自己的 service/account,不全局扫描秘钥库。