关于 Verax
Verax 是位于 Agent 与工具之间的 MCP 服务,通过策略门控、签名决策记录和事后效果核对,为需要审计与审批控制的 Agent 调用提供本机账本。策略无法自行决定的调用会等待操作员批准。
主要功能
- 01调用前执行策略门控
- 02记录签名决策与拒绝
- 03核对调用效果与记录
- 04人工审批待定调用
- 05本机独立验证账本
适用场景
- 01限制 Agent 的工具调用与外发
- 02要求操作员审批特定操作
- 03检查决策记录和调用效果
- 04离线验证账本签名
MCP 相关
Verax 作为 MCP 服务拦截 Agent 发出的工具调用,并在执行前进行策略判断和记录决策。它向 MCP 客户端提供受门控的工具调用,并保留调用效果以供核对。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @verax-ai/bodyVERAX_ISSUERIssuer the agent's token must carry. The body refuses to start without one; `verax doctor` names what is missing.VERAX_JWKS_URLWhere the body fetches the keys that verify that token.VERAX_AUDIENCEAudience the token must name, so a token minted for something else is refused.VERAX_STATE_DIRDirectory the ledger, keys and approvals live in. It stays on this machine.VERAX_POLICY_FILEPolicy the gate applies. @verax-ai/proxy ships policy/default.json, which denies what it does not name.VERAX_BINDhost:port the body listens on. Anything but loopback needs VERAX_TLS_TERMINATED=1.VERAX_INVENTORY_FILERoster document the body serves; the format is @verax-ai/inventory.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Verax
Agent 行动前会询问的主体。
收录于:npm · Glama · MCP Registry · MCP Market · mcp.so · Docker Hub · Zenodo
Verax 是一个位于 Agent 与其工具之间的 MCP 服务。每次工具调用都会经过策略关卡,并在执行前留下已签名的决策记录;每次实际执行的调用都会留下效果条目,之后会与其记录进行核对。拒绝与批准一样都会被记录。对于策略无法独自决定的调用,会先暂停,直到操作员批准;操作员可以在这台机器上批准,也可以在设置好操作员入口后,使用通行密钥从另一台设备批准。账本保存在主体运行所在的机器上,且只有配置好授权后,主体才会开放:没有默认令牌。
找出漏洞,我们就付费。 每份有效报告可获 100 美元,报告内容须能让 Agent 的账户绕过拒绝而获准执行调用、在没有决策记录的情况下执行调用,或更改服务的代码、密钥或账本。总预算为 500 美元。条款:SECURITY.md。
由 VERAX Teknoloji 开发。姊妹项目: Conarium · Tugra · Cedulon。决策记录使用 Cedulon 记录格式。
Verax 对比情况,日期为 2026 年 10 月 15 日:在 40 个会对 Agent 的工具调用进行拦截、记录或审批的项目中,有 9 个项目围绕 4 个问题进行比较,每个单元格都有来源;页面也说明了 Verax 的不足之处: verax-ai.com/compare.html。
查看运行效果
npx @verax-ai/body demo
这段录制是一次终端运行的输出,当时审批问题的回答是 y,并输入了金额。运行约耗时一秒;这里以慢速播放,方便阅读。
没有终端来回答审批问题时,命令会打印以下内容:
verax demo
memory.put / memory.get
allowed; two signed records
message.send -> [email protected]
refused egress-blocked (signed)
ref 6c6e4925-b769-4a8b-8fc4-e2443613a5b6
spend 100 minor USD sample-merchant
held
no terminal to ask, so it stays held (run this in a terminal to be asked)
audit.explain of the refuse
finding none
trust-root own-key
chain and signatures read back
records 5
effects 3
ledger removed on exit (run with --keep to keep it and check it with verax verify)
Not shown here: data masking arrives with a downstream server such as Conarium; statement reconciliation needs a real statement (verax reconcile).
Node 22.6 或更高版本,@verax-ai/body 0.2.1 或更高版本。该命令会记录一次允许的记忆写入和读取、一次针对策略列表之外主机的消息的签名拒绝,以及一笔等待本机操作员处理的付款(当终端回答 y 并输入金额 100 后即获批准;在 0.5.0 及更早版本中,演示不会打印第二个问题)。
--keep 会将临时账本保留在磁盘上。verax verify <dir> 可在没有主体的情况下读取账本,详见在没有我们参与的情况下读取账本。
保留并检查账本:
npx @verax-ai/body demo --keep
npx -y -p @verax-ai/body verax verify <the directory it printed>
同样的规则,动画呈现
四个简短片段展现了同一道关口,只不过角色取代了终端。它们是示例场景:画面由 three.js 绘制,配音由 ElevenLabs 生成。
第 1 集,“$1,850”:一笔付款会被暂扣,直到有人在手机上批准;只要将记录中的金额改动一美分,签名就会失效。
https://github.com/user-attachments/assets/772ae1c4-2697-47a0-a228-36f0508b0d93
第 2 集,“没有规则,就无法通过”:没有规则的调用会被拒绝;改用新名称再次发起同一调用,还是会被拒绝,而且两次拒绝都会被签名。
https://github.com/user-attachments/assets/4fb86627-3310-4f10-b1a9-059d8fcffb28
第 3 集,“红色拉杆”:操作员让主体停止运行,之后的每次调用都会被拒绝并签名,而已经在运行的调用不会被中断。
https://github.com/user-attachments/assets/8d19eed9-3359-46b3-bd77-f2b1b1c4dd75
第 4 集,“谁批准的?”:一笔暂扣的支出会一直等待,直到有人在机器上运行 verax approve;Agent 无法批准这笔支出,批准者的操作员 ID 会写入记录。
https://github.com/user-attachments/assets/0b8aade4-a970-4b63-835e-4837e2a39cc9
连接你的 Agent
提升权限运行的 verax install 和 verax approve 会运行此程序的副本,只有管理员可以更改该副本;如果副本可由你的账户更改,则会拒绝运行。在 Windows 上,可以通过操作员入口(verax install --operator-door <origin>)使用通行密钥批准,无需提升权限的 Shell;如果没有设置操作员入口,则需要通过提升权限的 CLI 运行 approve。必须从另一个管理员账户运行,而不是在此账户下提升权限运行,因为同一用户的提升权限 Shell 会继承该用户的环境变量和 PowerShell 配置文件,而 Agent 可以设置这些内容。在该 Shell 中清除 NODE_OPTIONS(Remove-Item Env:NODE_OPTIONS)。使用另一个账户启动 PowerShell 时加上 -NoProfile(否则提升权限的 Shell 会运行你的 $PROFILE,而你的账户可以更改它):
npm install -g --prefix "$env:ProgramFiles\verax-cli" @verax-ai/body
& "$env:ProgramFiles\verax-cli\verax.cmd" install
在 Linux 和 macOS 上,使用 root 所有的 Node(发行版提供的 /usr/bin/node,或 /opt/verax-node/<dir>/bin/node;如果你启动安装程序时使用的 Node 可由你的账户更改,安装程序会打印这些步骤)。不要使用 env node 启动提升权限的命令:
sudo npm install -g --prefix /opt/verax-cli @verax-ai/body
sudo /usr/bin/node /opt/verax-cli/lib/node_modules/@verax-ai/body/dist/cli.js install
该命令会在签名检查后,从 npm 注册表将 @verax-ai/body 安装到管理员所有的目录中,运行该 Node,并将账本保存在服务账户下。在 Windows 上,Agent 令牌位于 %ProgramData%\Verax\agent-token\<your SID>\agent.token(Administrators 和 SYSTEM 拥有完全控制权限,你的 SID 可以读取该文件,并对目录拥有读取和执行权限)。在 Linux 和 macOS 上,以你的 uid 运行的子进程会从标准输入将令牌写入 ~/.verax/agent.token。它会打印读取该文件的 Claude Code 配置行。端口 8787 已被占用?使用 verax install --port 8797。在 Windows 上,Node 必须由 nodejs.org 提供、面向所有用户安装;如果 Node 可由你的账户改写,则会拒绝运行。在 macOS 上,解决方法是以 root 身份将官方 tarball 解压到 /opt/verax-node(root:wheel,组和其他用户均不可写)。在 Linux 上,路径相同,为 /opt/verax-node(root:root),SELinux 会将其标记为 usr_t。在 SELinux 系统上,安装要求 Node 的标签为 bin_t 或 usr_t(发行版提供的 Node 符合要求;位于 /usr/local/lib 下的 tarball 则不符合),并会打印一行修复命令。随后,服务会以 unconfined_service_t 运行。服务账户和文件权限构成安全边界。
使用 verax approve 批准被暂扣的调用;或者,如果安装时指定了 --operator-door,则可通过其他设备上的操作员入口,使用通过 verax operator enroll 配对代码注册的通行密钥进行批准。通行密钥面板(verax desktop)尚未发布。在 Windows 上,请从另一个管理员账户运行批准命令,而不是在此账户下提升权限运行;在运行过 Remove-Item Env:NODE_OPTIONS 的 -NoProfile PowerShell 中执行:& "$env:ProgramFiles\verax-cli\verax.cmd" approve。在 Linux 和 macOS 上,指定 root 所有的 Node:sudo /usr/bin/node /opt/verax-cli/lib/node_modules/@verax-ai/body/dist/cli.js approve 或 sudo /opt/verax-node/<dir>/bin/node /opt/verax-cli/lib/node_modules/@verax-ai/body/dist/cli.js approve。卸载时也使用相同方式,将 approve 替换为 uninstall。
若要在你自己的用户账户下试用(这不构成安全边界):
verax init --local ~/.verax
verax serve --env-file ~/.verax/verax.env
claude mcp add --transport http verax http://127.0.0.1:8787/mcp --header "Authorization: Bearer $(cat ~/.verax/local-issuer/agent.token)"
令牌可以通过安全闸读取和写入记忆,但不能批准调用。随附策略会拒绝 spend,直到你为其添加规则;被策略暂扣的调用会等待你在此机器上运行 verax approve,或者在设置了操作员入口后通过该入口批准。参见 docs/THREAT_MODEL.md。
使用 Conarium
@verax-ai/body 0.2.2 及更高版本接受 --with-conarium。0.2.1 不包含此标志。该标志会让 npx 从 npm 下载 @conarium-ai/core 并将其作为子进程运行;这需要网络连接。
Conarium 会屏蔽各行,其示例策略会拒绝访问 public.secrets 表。Verax 会让每次调用都经过与自身工具相同的关卡,保留签名记录和答案的哈希,并在子进程看到调用之前,拒绝策略未列出的下游工具。Conarium 返回错误时,body 会告知调用方发生了错误,但不会透露错误内容。
在没有终端可回答审批问题的情况下,它会输出:
verax demo
memory.put / memory.get
allowed; two signed records
message.send -> [email protected]
refused egress-blocked (signed)
ref 6c6e4925-b769-4a8b-8fc4-e2443613a5b6
spend 100 minor USD sample-merchant
held
no terminal to ask, so it stays held (run this in a terminal to be asked)
conarium.query customers
allowed; masked by Conarium before the rows left it
measured [MASKED_PII] on every email and card
conarium.query public.secrets
allowed by this gate; Conarium answered with an error and no rows
recorded as a failed call
conarium.list_tables
refused no-rule (signed)
refused by this gate; the downstream server never saw the call
audit.explain of the refuse
finding none
trust-root own-key
chain and signatures read back
records 8
effects 5
ledger removed on exit (run with --keep to keep it and check it with verax verify)
Not shown here: a real database (these are Conarium's sample rows); statement reconciliation needs a real statement (verax reconcile).
随附内容
| Package | 内容 |
|---|---|
@verax-ai/body | MCP 服务和 verax 命令:serve、install、uninstall、init、doctor、approve、operator、downstream、reconcile、witness、halt、resume、unlock(desktop 尚未发布)。 |
@verax-ai/proxy | body 所基于的决策代理:策略、签名记录、账本、explain、reconcile。 |
@verax-ai/inventory | body 提供、面板列出的名册文档,以及其严格解析器。 |
这三个软件包会一起发布,并采用相同的版本;docs/STATUS.md 中的功能矩阵列出了当前版本,该版本也就是 npm 上的版本。该 body 也已列入 MCP 注册表,名称为 io.github.verax-ai/verax。该版本包含什么、不包含什么,以及支撑每一行的测试,都列在 docs/STATUS.md 顶部的功能矩阵中。
在没有我们的情况下读取账本
只有供应商运行中的服务才能读取的账本,只能证明买家是在租用,而不能证明他们持有。verax verify 会独立读取一个状态目录——无需任何服务监听,也不需要网络连接——并将每项检查分别列在一行,因为它们可能各自失败。对 npx @verax-ai/body demo --keep 留下的账本副本运行该命令,0.6.0 会输出:
$ verax verify ./verax-state
ledger ./verax-state
decisions 5
effects 3 (3 bound to a decision, 0 with none)
signatures 5 verify, 0 do not
chain unbroken
verified with the key carried in these files
verified against the key carried in the records themselves: this shows the files are internally consistent, not that the key was ever trusted. Pin a key you hold to check that.
effects with the key carried in these files
verified against the key carried in the self effects themselves: this shows the files are internally consistent, not that the key was ever trusted. Pin a key you hold to check that.
same-org with no key
no same-org effects, so no witness key was used
checkpoints with no key
no checkpoints, so no checkpoint key was used
index: 5 ref(s), each still a decision
effect completeness checked
inputs: 5 record(s), each with its inputs row
tail: no checkpoint; removing the newest records with their effects is not detectable from these files
control: no control records
anchors: none (no checkpoint is registered with a transparency service)
approval signatures signed-verified 0 · signed-failed 0 · unsigned-http 0 · cli 0
no operator key was found in these files
control signatures signed-verified 0 · signed-failed 0 · unsigned-http 0 · cli 0 · file 0
starts 1; largest gap none; previous beat missing at 1792241614080; 1 of 1 signed verify under the in-ledger record key
VERIFIED
演示不会批准任何内容,也不会停止任何内容,因此两项签名计数均为零;通过操作员入口给出的批准会计入 approval signatures 行(远程批准)。tail
和 anchors 与下文所述的检查点有关。starts 汇总心跳(留意静默)。
verified with the key carried in these files 这一对结果是关键。使用账本旁边的密钥检查账本,只能证明这些文件彼此一致,除此之外什么也不能证明——任何能够写入账本的人也能写入该密钥。传入
--key <public.pem>,即可使用你持有的副本验证决策记录,此时结果会显示 a key you supplied。效果使用单独的密钥签名。self 行使用效果密钥检查:固定密钥时使用 --effect-key <public.pem>,否则使用从第一条 self 行中提取的一个密钥。same-org 行使用见证密钥检查:固定密钥时使用 --witness-key <public.pem>,否则使用从第一条 same-org 行中提取的一个密钥。如果存在 same-org 行,固定 --effect-key 时也必须提供 --witness-key;如果存在 self 行,固定 --witness-key 时也必须提供 --effect-key;否则结果不会通过验证。每一行表达的意思都一样:这些文件彼此一致,但这并不能证明该密钥曾经属于你。检查点由见证密钥签名。每条检查点记录都使用一个密钥检查:固定密钥时使用 --checkpoint-key <public.pem>,否则使用从检查点文件中提取的一个密钥;同样要注意,这只能证明一致性,不能证明可信度。尾部计数只统计签名验证通过的检查点。能够改写这些文件的人仍可将该文件回滚到较早的有效前缀,同时保留其后的记录;只有保存在别处的检查点才能检测到这一点。--json 会为管道输出相同结果;验证通过时退出码为 0,否则为 1;目录中没有账本时,绝不会静默地报告成功。
记录采用 COSE_Sign1,算法为 -19(Ed25519,RFC 9864),而不是较早的多态算法 -8(EdDSA)。有些 COSE 库尚不认识 -19:截至 go-cose 1.3.0 和 pycose 1.1.0,两者都会拒绝它;相关支持进展见 go-cose#224 和 pycose#126。
verax verify 不依赖这两个库。
我们之外的验证器
test-vectors/ 是一组冻结的账本,每个账本都附有验证结论,以及验证器应报告的阶段。两位使用各自验证器的人已在 vectors-v1 上运行这组测试并公布结果:
- Tymofii Pidlisnyi(Agent Passport System)使用 APS 一致性测试套件中的运行器:对全部 16 个向量进行逐阶段的部分比较,而不是给出完整账本结论 (运行结果)。
- Roberto Locatelli(cryptovalid-opencore)使用根据草案、RFC 和向量 README 编写的独立检查器:在使用见证密钥验证检查点后,16 个验证结论中有 16 个一致,首次失败阶段有 16 个中的 15 个一致。其中一个匹配依据的规则是在阅读向量后添加的,运行结果本身也说明了这一点 (运行结果)。
匹配的运行结果表明,另一个验证器能够读取这些编码,并在相同阶段得出相同结论。这并不构成对该服务端的独立审计。
安装
npm install -g @verax-ai/body
verax --help
verax doctor
无法访问 npm registry 的主机可以从离线软件包安装;步骤见 docs/OFFLINE_INSTALL.md。
在所有进程都以提升权限运行的账户上(内置 Administrator,或 EnableLUA=0),来自用户可写 npm 前缀的命令会被拒绝;请使用由管理员所有的 %ProgramFiles%\verax-cli 副本。
需要 Node 22.6 或更高版本。主体通过 Streamable HTTP 在 VERAX_BIND(默认为 127.0.0.1:8787)上的 /mcp 提供 MCP 服务,并且在开始监听前需要颁发者、JWKS URL、受众、状态目录和策略文件;verax doctor 会指出缺少的内容。变量和运行步骤见 packages/body/README.md。
工具
策略决定令牌的作用域可以调用以下哪些工具;
packages/proxy/policy/default.json 会拒绝未列出的内容。
| 工具 | 描述 |
|---|---|
memory.get | 在门控机制后读取一条按租户存储的记忆项。 |
memory.put | 在门控机制后写入一条按租户存储的记忆项。 |
audit.explain | 从签名账本中读取一项决策及其链、签名和发现。 |
message.read | 读取收件箱。 |
message.send | 写入发件箱;只能访问策略允许列表中的主机。 |
spend | 授权并记录一笔付款,受策略规定的上限、收款方列表和每日限额约束;策略要求时会交由操作员处理。主体不会转移资金。 |
主体在门控机制之外的功能
以下每一行都是 docs/STATUS.md 中能力矩阵的一行,其中说明了对应版本、它不具备的功能,以及当其不再成立时会失败的测试。
- 审批:待处理的调用可在本机通过
verax approve批准,也可从其他设备通过操作员入口批准;该入口使用通行密钥和针对该请求的断言。除非为其指定来源,否则入口处于关闭状态。在 Windows 上,CLI 审批命令由单独的管理员账户运行。verax desktop中的通行密钥面板尚未发布。审批者的操作员 ID 会通过哈希绑定到签名记录中。 - 见证:
verax witness从第二个进程为效果记录签名,并写入持久检查点;没有它,见证类别会保持为self。 - 停止与撤销:
verax halt会将所有后续调用转为带签名的拒绝;被撤销的令牌 ID 会在写入任何记录前遭到拒绝。 - 对账:
verax reconcile会将记录的支出与信用卡账单导出数据进行匹配,并列出匹配项、幽灵项以及已授权但未付款的记录。 - 租户密钥:记忆和收件箱存储在由令牌的颁发者和主体派生的密钥下;对于其他租户的 ID,会返回带签名的拒绝。
- 限制:速率和每日计数器、无法记录拒绝时的低磁盘空间拒绝(HTTP 507),以及出站流量允许列表;无法读取的计数器会采用默认拒绝策略。
- Doctor 和心跳:在首次调用发现问题之前,
verax doctor会指出缺失或过期的内容。
留意静默
运行中的机体即使空闲也会脉动(默认每 10 s 一次;
VERAX_HEARTBEAT_EVERY_MS,最小为 1,000 ms)。starts.jsonl 中的启动记录
会记录与上一次脉动之间的间隔;verax verify <stateDir> 可离线汇总
这些间隔。自 0.5.0 起,启动记录由记录密钥签名。
verax watch ./verax-state --max-silence 30s
verax watch ./verax-state --once
verax watch --url https://host/healthz --token-file ./audit.token --once
verax watch ./verax-state --on-silence exec --exec "node isolate.mjs"
无法读取、过期或时间远在未来的脉动均视为静默。本地监视默认会停止;恢复后不会自动继续。操作员必须使用现有的
恢复路径。远程监视会报告静默,但无法远程停止。令牌只从文件读取;除回环地址外,必须使用 HTTPS。exec
命令会在每次静默事件中运行一次,其环境中包含 VERAX_WATCH_REASON,且不会通过 shell 运行。可执行文件或参数中包含空格时请加引号。
--once 在运行正常时以状态码 0 退出,静默时以 3 退出,用法错误时以 2 退出。持续监视会在每次静默事件和恢复时输出一行
JSON,并以 max-silence/3 为轮询间隔。请在操作员选择的位置运行;同一主机上的监视器与该主机共享信任,如果账本和监视器都消失,则不能作为独立证据。
连接客户端
机体默认监听 http://127.0.0.1:8787/mcp。客户端
配置如下所示;令牌由你的签发方提供。
{
"mcpServers": {
"verax": {
"url": "http://127.0.0.1:8787/mcp",
"headers": { "Authorization": "Bearer <token from your issuer>" }
}
}
}
状态
树中包含的内容以及仍未得到证实的内容,都在
docs/STATUS.md 中逐项说明。本仓库中的任何内容都不构成超出该文件所述范围的声明;其中的段落也不代表一次发布。威胁模型见
docs/THREAT_MODEL.md;漏洞报告方式见
SECURITY.md。
树中还有什么
apps/panel是用于说明账户去向的界面:从签名账本读取记录列表、黑匣子和状态视图。私有;不会发布。 面板会话使用代码流程;访问令牌仅保存在内存中,并会在刷新时丢弃。Vite 仍可能在请求没有 Authorization 标头时,将.env.local中的VERAX_DEV_TOKEN附加到/api(桌面 MCP 大脑和测试)。scripts/dev-issuer.mjs仅用于开发;不是生产环境授权服务器。它提供GET /authorize(PKCE S256)和POST /token,将令牌写入--out,且从不打印令牌。它监听VERAX_DEV_ISSUER_PORT(默认 8790)。设置NODE_ENV=production时会退出。scripts/demo-box.mjs仅用于开发:单个进程,在回环地址上启动开发签发方和机体,并使用临时账本;通过签发方的代码流程为自身签发短期令牌,并通过 stdio 使用 MCP,适用于无法持有自身令牌的沙箱,例如目录的 构建检查。它不会更改机体:每次调用仍须通过闸门并会被记录,spend始终处于拦截状态,也没有操作员在场批准。设置NODE_ENV=production时会退出。不用于部署。
开发
npm ci
npm test # guards, build, typecheck, unit and cost suites, panel
npm run pack:smoke # pack the three packages and install them elsewhere
CI 会以非 root 用户在 Linux 上运行测试套件,并在 Windows 上再次运行,同时执行代理性能检查。发布从 Actions 选项卡发起:
release.yml 使用 npm 可信发布和来源证明来发布三个包,随后 mcp-registry.yml 会在 npm 确认新版本后更新注册表记录。
这两个工作流都不会在推送时运行。
每次发布都会在 docs/PLATFORMS.md 中列出的平台上进行测试,每行均链接到对应的 CI 运行记录。
如需贡献,或报告在未列出平台上的运行情况,请参阅 CONTRIBUTING.md。
许可证
Apache-2.0。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。