Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

kcenv

kcenv 是一个跨平台轻量环境变量秘钥管理脚本。

它适合把 OPENAI_API_KEYANTHROPIC_API_KEYREDMINE_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 和 POSIX sh 导出格式。
  • 变量值不会写入仓库或 shell 配置文件。

安全模型

kcenv 使用统一的命名空间:

service = kcenv
account = __KCENV_KEYS__      # 内部索引,只保存变量名列表
account = OPENAI_API_KEY      # 真实秘钥值
account = REDMINE_API_KEY     # 真实秘钥值

kcenv listkcenv export 只读取 __KCENV_KEYS__ 中登记过的变量名,然后逐个精确读取:

# macOS
security find-generic-password -s kcenv -a NAME -w

# Linux
secret-tool lookup service kcenv account NAME

它不会执行全局秘钥库 dump,也不会枚举其他 service。

安装

1. 安装平台依赖

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

2. 安装 kcenv

复制脚本到 PATH

mkdir -p ~/.local/bin
cp bin/kcenv ~/.local/bin/kcenv
chmod 700 ~/.local/bin/kcenv

确认可用:

kcenv --help

fish 自动加载

创建 ~/.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
codex

POSIX sh/bash/zsh 可以使用:

eval "$(kcenv export --sh)"
your-command

如果只想给一个命令临时注入,可以启动一个子 shell:

sh -c 'eval "$(kcenv export --sh)"; exec "$@"' -- your-command arg1 arg2

AI Agent 如何读取

AI Agent 通常有两种读取方式:继承启动环境,或 在任务中显式调用 kcenv

方式一:启动前注入环境

这是最推荐的方式。先在 shell 中加载 kcenv,再启动 agent:

kcenv export --fish | source
codex

也可以启动其他 CLI agent:

kcenv export --fish | source
claude
kcenv 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 自己调用 kcenv

在自动化脚本或 agent 任务中,也可以直接读取某个变量:

export OPENAI_API_KEY="$(kcenv get OPENAI_API_KEY)"

这种方式适合只加载少数 key,但要注意:能执行 shell 命令的 agent 也能调用 kcenv get NAME 读取对应秘钥。

常见 Agent 接入方式

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

Codex CLI 可以继承启动环境:

kcenv export --fish | source
codex

API 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

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_KEYapiKeyHelper

pi

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.jsonapiKeyheaders 支持 $ENV_VAR${ENV_VAR}!command 和字面量。

OpenCode

OpenCode 可以继承环境变量:

kcenv export --fish | source
opencode

OpenCode 官方推荐通过 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 这两种保守方案。

fish 自动加载的限制

如果你安装了 ~/.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 只显示变量名,但变量名本身也可能透露服务信息;需要时避免在日志中输出。

Skill

仓库包含一个 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 命名空间。
  • 不扫描全局秘钥库。
  • 修改前先说明影响范围。
  • 写入后用长度/哈希/一致性检查验证。

排错

fish -c 里没有变量

如果 hook 写在 if status is-interactive 中,非交互 fish -c 不会自动加载变量。这是预期行为。

需要时显式加载:

fish -c 'kcenv export --fish | source; your-command'

macOS Keychain 弹窗

首次读取某个条目时,macOS 可能要求允许 Terminal/iTerm/Warp 访问 Keychain。允许后一般会缓存。

Linux secret-tool 未找到

安装 libsecret-tools(见上方安装说明)。Arch 用户安装 libsecret 即可。

Linux keyring 未解锁

桌面登录后 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 --all

kcenv 的设计目标是只精确读写自己的 service/account,不全局扫描秘钥库。

About

Cli to manage secrets with macOS KeyChain or Linux secret-tool

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages