本地保险库 · MCP · CLI

密钥
从不进入上下文

KeyGrantX 把密钥锁在你自己机器里。模型只看得见名字;值只在获批的那一条命令的子进程环境里出现一瞬,回给模型的输出再脱敏。

macOS · Windows · Python ≥ 3.10 · 不需要云端

会话 · claude-code
模型上下文 模型能看见的

            
STRIPE_SECRET_KEY 值 · 不可见

          
子进程环境 值只在这里
STRIPE_SECRET_KEY=···

值在 exec 时解密,只写进环境变量。

问题

上下文就是泄露面。
加密解决存储,不解决"出现"。

密钥一旦被读进会话,它就留在了那里——被 prompt injection 读一次,被日志记一次,被写进生成的代码再一次。

  • 提示注入

    一句藏在 README、issue 或网页里的指令,就能让代理把上下文里的密钥打印出来。它不需要提权,只需要被读到。

  • 日志与 trace

    会话存档、错误上报、截图、录屏。任何一环落盘,明文就躺在那里,而且没人记得去删。

  • 生成的代码

    模型"顺手"把 key 写进 .env.example 或测试夹具,再被提交进 git——这类事故从来不是攻击,只是习惯。

边界

给模型名字,
给进程值。

KeyGrantX 只做一件事:在边界上把"名字"和"值"分开。分开了,上下文就不再是攻击面。

存在哪
本机加密保险库。Windows 用 DPAPI,macOS 用 Keychain,Linux 用 Secret Service。
听哪个端口
只监听 127.0.0.1:17831,被占用就顺延,永远不暴露到局域网。
谁能用
持有同一份保险库的进程。审批由你点,授权只在内存里,进程一退就没了。
模型名字
闸门审批
进程值
三层,三种权限。值不下沉到最上面一层。

怎么工作

四个动作,
一次都不经过模型。

  1. 01

    请求

    代理调用 exec_with_secrets,传给它的是名字。MCP 里根本没有"写密钥"的工具——要写,只能在终端里写。

  2. 02

    审批

    原生对话框弹在最上层,显示完整命令,超长命令直接拒绝而不截断。60 秒不点,等于拒绝。

  3. 03

    注入

    解密只发生在执行进程内。值进环境变量,命令行参数里没有,stdout 里也没有。

  4. 04

    脱敏

    回给模型的输出里,明文以及 base64、hex、URL 编码变形,全部替换成 ••••。第二道防线,不是唯一一道。

KeyGrantX 审批对话框:显示密钥名、完整命令、授权范围与有效期,默认 60 秒后自动拒绝
真实的审批框。它显示的是完整命令,不是"某条命令"。

演示

十九秒。
一次请求,四次交接。

从代理开口要密钥,到你按下批准,再到值进出子进程、输出被脱敏——中间没有一个字节回到模型。

Remotion 渲染 · 1920×1080 · 无声循环

产品

一个保险库,
三个入口。

托盘常驻、本地控制台、MCP server。它们读同一份状态——控制台里发的授权,MCP 那边立刻看得见,反过来也一样。

两种授权

严格是默认。
轻巧要验证码。

严格

默认 · 免费

绑 sha256(命令) + 你勾选的那几个密钥。

  • 换一条命令就要重新审批
  • 不需要验证码
  • 默认 15 分钟过期

轻巧

需要验证码

只绑你勾选的那几个密钥,任何命令都能用。

  • 适合连续跑一串命令
  • 开启前先验证系统账户密码
  • 你在有效期里不再逐条审阅——这是明码标价的交换

它不防什么

安全产品最该说清楚的,
是边界在哪结束。

网络外带

被攻陷的代理可以申请一条把密钥发出去的命令。控制点是审批框——它显示完整命令,所以要看。

间接执行

批准 sh deploy.sh,等于批准这个脚本做的一切,包括代理自己刚写进去的那段。

同用户进程

以同一个系统账户运行的程序能读保险库。KeyGrantX 管的是代理的访问,不是本机恶意软件。

每一条都写在 README 的 Threat model 里,没有藏在脚注。

安装

两行命令,
然后把它忘了。

装完它就在托盘里待着。你只在审批框弹出的时候需要它。

Windows 有 per-user 安装包,不需要管理员权限;
卸载不会删掉你的保险库。

terminal
# 装 CLI 与 MCP server
uv tool install keygrantx
# 给当前项目接上 .mcp.json 与使用说明
keygrant init
# 首次存一个密钥(值走 stdin,不进 argv)
keygrant set STRIPE_SECRET_KEY

密钥回不到模型里。