为你的开发机器提供即时凭证。
状态: 仅支持 macOS(Apple Silicon),且仍在开发中。
你的机密信息以明文形式散落在机器各处:.env 文件、~/.aws/credentials、~/.zshrc 中的导出变量、.npmrc 令牌、MCP 配置。任何以你的身份运行的程序都能读取它们。一次糟糕的 curl | sh、一个可疑的 npm install,或者现在以你的完整权限运行在编辑器中的某个 AI 代理。
jit 将每个机密信息移入由 Touch ID 保护的本地加密保险库,并重写文件,使你的工具继续正常工作。磁盘上现在只有一个诱饵。真正的值只会在生物识别提示后,以内存形式出现在请求它的特定进程中。结果是:你只需解锁一次,jit 在将凭证交给工具(或代理)之前会先询问,其余时间磁盘上只有一个诱饵。
| 由 Code 启动 | 由 claude 启动 |
|---|---|
![]() | ![]() |
它不做什么: 它不会让一个已被入侵的账户变得安全,也不会在机密信息进入请求它的进程内存后保护它。边界在一页上明确说明: 刻意设定的限制。
没有内核扩展、没有文件系统驱动、没有 FUSE。三种机制,根据工具能做什么来选择:
execve。 jit 自身的镜像被你的命令替换,因此值只存在于那一个进程中,jit 从内存中消失。credential_process、docker 和 git 凭证助手、kubectl exec 插件、Terraform 的凭证助手。工具询问,jit 应答,不涉及任何文件。该挂载是一个 POSIX FIFO,使用 mkfifo(2) 以 0600 模式创建。调用 open(".env") 的程序会在内核中阻塞,直到有写入者连接。后台服务就是那个写入者:它以 O_WRONLY 打开路径,释放读取者,将内存中的解密字节写入内核管道缓冲区,关闭,然后循环回到 open(2) 等待下一个读取者。不涉及磁盘。写入的内容按每次读取决定:对普通读取者提供诱饵,只有在你授权的运行中才提供真实值。
调用者身份用于解释和审计,但从不做决定。 进程名是可以伪造的,快速关闭的 FIFO 读取者可以完全逃避识别。回答提示的人类才是门禁;进程名只是告诉你该回答什么。完整细节见 工作原理 和 实时挂载。
brew install jitpass/tap/jitpass
这是推荐路径,对于安全工具来说,原因很重要。发布版本使用 Apple Developer ID 签名并由 Apple 公证。Homebrew 会隔离下载的内容,因此 Gatekeeper 在允许二进制文件运行之前会对照其公证票据进行检查。如果你想自己验证而不是听我们的一面之词,运行 jit doctor:其 jit 行报告 signed CZC6BH93GJ,这与 jit upgrade 在安装任何内容之前运行的检查相同。
curl -sL https://dl.jitpass.com/jitpass/jit/releases/latest/download/jitpass_darwin_arm64.tar.gz | tar -xz jit
shasum -a 256 jit # 与发布页面上的 checksums.txt 对比
codesign -dv --verify --verbose=2 ./jit # 预期:Developer ID, TeamIdentifier=CZC6BH93GJ
sudo mv jit /usr/local/bin/
这是为没有 Homebrew 的人准备的,而且这确实是较弱的路径:curl 不设置隔离位,因此 Gatekeeper 永远不会查阅公证票据,go install 也是如此。二进制文件仍然已签名且已公证,所以上面的两行可以让你在运行前检查两者,但你必须实际运行它们。如果你有 Homebrew,请使用 Homebrew。
仅支持 Apple Silicon。在 Intel Mac 上,使用 go install github.com/jitpass/jit/cmd/jit@latest 从源码构建。
选择一条路径。如果你之前从 tarball 安装过,现在切换到 Homebrew,请在 brew install 后删除旧副本(sudo rm /usr/local/bin/jit);否则两个 jit 会同时在 PATH 上分别升级,jit doctor 会标记出来。
升级: brew upgrade jitpass,或 jit upgrade:一个经过验证的自更新(在替换前同时检查 Developer-ID 签名和校验和,重启服务)。无论哪种方式,你的保险库都不受影响。
Homebrew 会随二进制文件安装 shell 补全,因此 jit <TAB> 可以补全子命令、标志、保险库路径和可包装的工具名称。从 tarball 或源码安装的话,自己添加:
echo 'source <(jit completion zsh)' >> ~/.zshrc && exec zsh
无论哪种方式,jit doctor 都会告诉你补全是否到达了你的 shell。
jit scan # 只读。不修改它扫描的任何文件,不打印真实值。
jit vault init # 创建保险库(主密钥在你的登录钥匙串中)
jit migrate --dry-run # 预览整个机器范围的修复计划
jit migrate # 应用它:显示计划,询问 [y/N],一次 Touch ID
jit migrate ~/code/myapp # 或只修复一个项目
jit run -- npm run dev # 运行你的工具;真实值仅注入到该进程中
不带路径的 jit scan 会扫描你的整个主目录,所以如果目录很大请给它一点时间。要直接针对某个位置,指向一个路径:jit scan ~/.aws。
日常使用主要是 jit run -- <cmd>。对于自带登录令牌的 CLI(gh、glab、stripe 等),你只需 jit wrap gh 一次,然后像往常一样继续输入 gh。
不确定某样东西是需要 jit wrap、jit migrate 还是什么都不需要?你不需要知道。jit scan 将找到的所有内容分为 jit 将保护的部分(一条命令 - 包括包装)和只有你能修复的部分,而裸 jit migrate 会运行整个计划:
$ jit scan
YOUR SECRETS: 7 — 0 protected by jit (0%)
▱▱▱▱▱▱▱▱▱▱ to 100%: one command +71% · 2 secrets only you can fix +29%
jit will protect these — 5 secrets in 4 files, 0% → 71%
→ jit migrate
~/.zshrc STRIPE_API_KEY, DB_PASSWORD
~/.config/gh/hosts.yml GitHub CLI token · wraps gh
...
only you can protect these — 2 secrets, 71% → 100%
[rotate, then delete every copy]
! A production database password in 2 files
→ rotate it now, then delete every copy
(jit scan --full 仍然提供经典的按类别分类清单,包含严重级别,包括 可包装的 CLI 令牌 部分。)
迁移一次凭证,然后继续像往常一样使用工具。
# AWS(以及 Terraform 和所有 AWS SDK)
jit migrate ~/.aws/credentials # 密钥移入保险库;不再有明文文件
aws s3 ls # 按需从保险库解析。无前缀,无标志。
terraform apply # 相同的凭证,相同的命令
# GCP 应用默认凭证(机器级凭证)
jit migrate ~/.config/gcloud/application_default_credentials.json
terraform apply # google provider 读取 ADC;Touch ID 提示后即可工作
# Docker / docker-compose
jit migrate ~/.docker/config.json # 注册表登录移入保险库
jit run -- docker compose up # jit 为此运行注入它们
docker login ghcr.io # 仍然有效;助手存储到保险库
# 曾经位于 ~/.zshrc 中的 shell 导出
jit migrate ~/.zshrc # 留下一行钩子;新 shell 只需拥有变量
./deploy.sh # 读取这些变量的脚本无需修改即可工作
# 你曾经在提示符下输入、现在位于 shell 历史中的令牌
jit migrate ~/.zsh_history # 每个都移入保险库;你的命令保留,机密信息不保留
jit guard history # 并阻止下一个被记录(zsh)
# (裸 `jit migrate` 也会在要求你确认的计划中提供此选项)
# 自带令牌的 CLI(gh、stripe、glab)
jit wrap gh # 一次性
gh pr list # 每次调用注入令牌,永久有效
每个工具第一次请求真实凭证时,jit 会询问一次,并记住你的回答直到保险库锁定。参见 两个 Touch ID 时刻 了解这如何叠加在保险库解锁之上、--trust 的作用,以及如何关闭按工具提示。
为什么有些工具无需设置而其他工具需要 jit run?一条规则:工具能否自己向 jit 请求机密信息? AWS(通过 credential_process)、登录时的 shell 以及 docker 的注册表登录(通过凭证助手)都可以,所以你不需要额外输入任何内容。只能在运行时读取文件的工具(docker compose、普通 SDK)无法请求,因此 jit run 将值交给它们。
机器级凭证文件(GCP ADC、sops、npm、netrc)的日常使用方式相同:运行你的工具并批准按进程提示。仅当你想要显式指定时才添加 jit run --with <name>:用于没有提示可回答的脚本和 CI,或当你想要一个项目自身配置永远无法触及的硬性门禁时。支持的工具 列出了每个工具需要输入的确切内容,以及每种工具的交付方式。
jit 在两个不同的时刻要求你的指纹,执行两个不同的任务:
jit 时,一次 Touch ID 会在整个会话期间打开保险库(5 分钟活动后重新锁定;无论你多忙,最长不超过 8 小时)。你解锁一次,而不是每条命令一次。jit 会在交出之前询问并指明请求者是谁。这可以阻止你没有运行的程序在保险库打开时悄悄使用你的密钥。$ aws s3 ls
Touch ID -> unlock your vault # 门禁 1:打开保险库 5 分钟
Touch ID -> aws wants your aws credential # 门禁 2:此工具,此凭证
...your buckets...
$ aws s3 cp ./file s3://bucket/ # 同一工具,同一会话:无提示
$ terraform apply
Touch ID -> terraform wants your aws credential # 不同的工具:它会自行询问
门禁 2 是防止已解锁的保险库变成自由放任状态的关键:即使你自己使用过 aws,一个可疑的 npm install 请求相同的密钥仍然会触发一个指明其身份的提示,这样你可以拒绝。
不想要第二道门禁?关闭它;保险库锁定仍然保留(关闭它本身需要一次 Touch ID,因为它会重新打开它关闭的窗口):
jit service consent off # 保险库解锁时工具静默解析
jit service consent on # 再次按工具询问(默认)
需要同时启动需要多个凭证的任务?jit run --trust -- terraform apply 可以用一个手势批准整个运行的工具。完整细节:按进程同意。
jit grant两道门禁都假设有人类在场回答。一个通宵工作的 AI 代理、一次长时间构建、一个定时任务:屏幕锁定、会话断开、运行在一个没人会看到的提示上停滞。进程授权 将你的决定提前而不是移除它 - 一次 Touch ID,在你还在场时给出,明确指出你签署的内容:
$ jit grant --process claude --profile jamf --for 8h
Touch ID -> let claude under iTerm2 use 2 secrets (jamf) unattended for 8h
✓ granted g-7f3a2c81 claude -> jamf until 17:42
└ covers claude under iTerm2: 1 running now, any started before 17:42
在接下来的 8 小时内,你输入该命令的终端(及其启动的内容)下的每个 claude 都能无提示获取这些机密信息 - 包括屏幕锁定期间,以及你之后启动的会话:一个新标签页、下一个 claude、凌晨 3 点触发的脚本。被命名的是你的终端,而不是被信任的名称:机器上其他地方自称 claude 的程序不来自该进程树,也不会继承任何内容。授权在其截止时间结束、你退出该终端时结束,或在你输入 jit grant revoke 的那一刻结束(这不需要指纹 - 收回访问权限永远是免费的)。想要一个精确的进程,退出时即消失?使用 --pid。每次授权都会作为独立事件记录在审计跟踪中,因此第二天早上你可以准确读取你的代理在你睡觉时接触了什么。完整细节:进程授权。
你编辑器中的代理以你的身份运行,拥有你的权限,整天为你读取文件。这正是它的全部意义,也是为什么你仓库中的明文 .env 现在是一个与两年前截然不同的风险。jit 将代理视为一等公民,在四个方面:
jit migrate ~/.claude.json # MCP 服务器配置:密钥移入保险库,
# 每个服务器现在通过 `jit run` 启动
jit wrap claude # AI CLI 本身:claude、codex、gemini、
# cursor-agent、copilot、cline、opencode、kiro-cli
jit grant --process claude --profile myapp --for 8h
# 让它通宵工作而无需无人应答的提示
jit audit --parent claude # 读取它在你睡觉时接触的确切内容
claude 请求同一个机密信息,各自被指明。代理悄悄读取 ~/.aws/credentials 会触发提示,而不是静默成功。jit run 启动。 迁移后的 MCP 配置保存的是保险库路径而非密钥,因此配置文件本身可以安全地放在磁盘上,也可以安全地交给读取它的代理。.env 并直接读取的代理会得到占位值,且该读取会被记录。jit audit --parent claude 显示代理使用的每个机密信息、触发的每个提示,以及你拒绝的每一个。更多内容见 MCP / AI 工具 和 按进程同意。
每条 jit 命令和每次解锁都会记录在一个持久日志中,你可以使用 jit audit 读取,最新的在前,每个事件一行 key=value,因此它可以像真正的服务日志一样被 grep。命令参数会被遮蔽,因此日志可以证明命令运行过,而不会存储其携带的机密信息。
$ jit audit --since 1h
time=2026-07-24 10:15:04 level=info kind=cmd status=ok dur=312ms cmd="jit migrate ~/.aws/credentials" user=meni parent=claude
time=2026-07-24 10:16:22 level=info kind=use op="read a secret" cmd="aws s3 ls" parent=claude secrets=aws/default
time=2026-07-24 10:31:09 level=warn kind=unlock status=denied method=touchid-or-passcode cmd="node postinstall.js" parent=npm secrets=aws/default
中间一行是 jit 存在的意义所在:aws/default 被 aws s3 ls 读取,由 claude 启动。最后一行是你拒绝的提示:npm 下的 node postinstall.js 请求相同的密钥,被拒绝。jit 还会记录服务在其套接字处拒绝的内容(内核认为不属于你的进程,正在探测代理)为 kind=error。
使用标志而不是 grep 来缩小范围:--kind、--status ok|failed|denied、--since/--until(2h/3d 这样的时长或日期)、--parent claude、--secret aws、--user、--grep <regexp>。添加 --follow(-f)像 tail -f 一样实时流式查看新事件,或 --format json 获取机器可解析的转储。两部分都是保险库旁边的持久文件,因此它既能回答上周的问题,也能回答过去一小时的问题。
.env 文件、shell 导出、AWS 和 Terraform、kubeconfig、Docker 注册表登录、GCP ADC、.npmrc / .netrc 令牌、MCP 服务器配置、裸令牌文件、记录在 shell 历史中的凭证、可包装的 CLI(gh、stripe、vercel 等),以及在登录时铸造凭证的 SSO CLI(clisso)。在每种情况下,文件都继续工作,真实值按需来自保险库。
完整目录按每个工具需要输入的确切内容分组,见 支持的工具:它会随工具的添加或移除跟踪代码。任何未列出的内容仍可使用 jit wrap add 包装。
已经在使用 1Password 保存机密信息?安装其 CLI 后,jit migrate 会链接而不是复制:已存在于 1Password 中的值会以其 op:// 引用形式存入保险库,因此 1Password 仍然是记录系统,jit 通过上述所有机制即时交付该值(jit vault link 对手动处理单个机密信息做同样的事情)。
jit 从不销毁凭证。迁移 移动 值到保险库,并在原位置留下一个 可用的钩子(一个诱饵 .env、shell 配置中的一行 eval "$(jit export)"、~/.aws/config 中的 credential_process = jit …,或一个 PATH 垫片),因此你的工具可以按需继续解析它。凭证仍然存在,只是加密了而不是以明文形式存在。
而且每个更改都是可逆的。在触碰文件之前,jit 会将其加密备份到保险库中,因此 jit migrate undo 可以逐字节恢复:
jit migrate ~/code/myapp # 应用了修复,一次 Touch ID
# 改变主意了,或者出了问题?
jit migrate undo ~/code/myapp # 每个被触碰的文件都逐字节恢复
文档位于 docs/ 下,按任务组织:
git commit -s),无需 CLAPolyForm Perimeter License 1.0.0 - 仅限个人和公司内部使用免费。