treg run --server 远程执行原理:密钥永不到达你机器的完整机制(6层防护拆解)
【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址: https://gitcode.com/GitHub_Trending/treg/treg
treg 是一个开源的 agent 工具统一密钥网关(定位类似 “OpenRouter for agent tools”):用一把 treg 密钥即可调用 2000+ 供应商 API 与 CLI。本文拆解treg run --server远程执行模式的完整机制——供应商密钥如何在服务端解密、注入、执行、清理,以及为什么它从头到尾不会落到你的电脑上。
一、先搞清楚:treg 的三种“用到密钥但不持有密钥”
treg 的核心承诺只有一句话:供应商密钥永远由服务端保管,按次注入。围绕它共有三种执行方式:
| 方式 | 密钥在哪解密 | 适合场景 |
|---|---|---|
treg call | 服务端 | 直接代理 HTTP API 请求 |
treg run(默认--local) | 服务端下发、本机专用treg-run用户下短暂注入 | 需要访问本机文件或 localhost 的 CLI |
treg run --server | 全程只在服务端 | CLI 在服务器执行,密钥一个字节的明文都不经过你的机器 |
--local已经把密钥藏在一个你无法读取的专用系统用户之下(详见 local-run 架构文档);而--server(项目里称 Tier 0)更彻底:命令行工具根本不在你机器上运行,你的终端只负责把参数发上去、把输出流回来。
二、treg run --server远程执行的完整流程
步骤 1:客户端只上传“哪个工具、什么参数”
一条命令,比如treg run --server agentmail-cli inboxes list,客户端做的事少得惊人:它把{tool, args, timeout_s}打包,带着你自己的 treg 令牌 POST 到服务端的/run接口,然后把返回的stdout/stderr/exit_code原样写回终端——行为和“本地直接跑这个 CLI”完全一致。
整个客户端逻辑就几十行,见 _run_server。注意:这里上传的“钥匙”是 treg 令牌(证明你是谁),而不是供应商密钥——因为你机器上根本没有它。
步骤 2:白名单与权限校验,然后才解密
服务端的/run入口在 run_tool_server,执行前先过一道闸门:
- 必须是 member 及以上角色,沙箱演示组织直接 403;
- 走常规的每成员工具 ACL、deny 规则、每日调用额度;
- 二进制白名单:要执行的
bin必须在允许列表里(目录中已知的 CLI,管理员可用TREG_RUN_ALLOWED_BINS扩充)。白名单校验和实际执行调用同一个解析函数 resolve_exec_bin,保证“检查的”和“执行的”绝不可能是两个不同的命令。
校验通过后才轮到 collect_secret_env:按工具的cli.inject配置,在服务端把加密存储的供应商密钥解密成环境变量值。
步骤 3:净化环境 + 一次性 HOME——密钥只活在子进程里
这是防泄漏的关键设计,见 _child_env:
- 子进程不继承服务端进程的环境变量——因为服务端环境里放着
TREG_SECRET_KEY等所有服务端机密,继承等于“全家福”式泄漏; - 只给 CLI 运行所需的最小集:
PATH、语言环境、以及注入的密钥; HOME指向一个临时目录(mkdtemp(prefix="treg-run-"))。很多 CLI 会把登录态、token 缓存写进~/.config,这里让并发运行的不同组织各用各的“家目录”,互不串扰。
步骤 4:资源限额 + 超时 + 输出上限(防 DoS 沙箱)
在 子进程创建处 还叠了三层“笼子”:
- 独立进程组(
start_new_session):CLI 及其所有后代自成一组,随时可以整组处决; - POSIX 资源限额:限制 CPU 秒数与最大文件大小,并禁用 core dump——因为 core 文件会把注入的密钥连同进程内存一起倒到磁盘;
- 输出上限:每条流最多捕获 1MB(runner 顶部常量),失控的 CLI 撑不爆服务器内存;超时默认 120 秒、上限 600 秒(
--timeout可调)。
步骤 5:结束即清理 + 输出脱敏——两条“收尾”防线
- 整组击杀:无论正常退出、超时还是被取消,_kill_group 都会 SIGKILL 整个进程组。为什么正常退出也要杀?因为 CLI 可能偷偷 fork 了后台子进程,它继承了密钥还能活得比这次运行更久;
- 删掉一次性 HOME,配置缓存随之蒸发;
- 输出脱敏:返回前 _redact 把 stdout/stderr 中出现的密钥明文(比如某些 CLI 的
--debug配置转储)替换成***,长值优先替换,短值不会漏网。
也就是说:密钥的明文生命周期 = 子进程存活的那几十秒,且只存在于服务端。
三、并发控制与审计:谁在什么时候跑了什么
- 并发槽位:全局最多 4 个服务端运行、单用户最多 2 个,满了立刻返回 429 而不是无限排队(run_slot)——防止单个成员耗尽主机;
- 全量审计:每次运行都会写入运行台账——工具名、参数(内联出现的凭证样式的 token 会被脱敏)、退出码、耗时、调用方身份,见 audit.record_run。用
treg runs --limit 20或treg audit随时回查,团队成员都能看清“谁在什么时候、用哪个 API Key 跑了什么”。
四、怎么选:--server、--local 还是 treg call?
| 你的情况 | 推荐 | 理由 |
|---|---|---|
| 调 HTTP API | treg call | 最轻,无 CLI 参与 |
| CLI 要读你本机文件 / 访问 localhost | treg run(--local) | 密钥在treg-run专用用户下隔离,你仍无法读取 |
| 机器是共享的、CI 环境、或者“就是不想让密钥出现在这台机器上” | treg run --server | 密钥零落地,输出流回终端 |
| 团队想让某个工具固定走服务端 | treg cli shell start --server-for stripe,render | 按工具名路由,见 shell 文档 |
一个小坑提前说:--server、--timeout这类标志要放在工具名之前(treg run --server mytool -- ls),写成treg run mytool --server -- ls会被当成传给 CLI 的参数,cmd_run 会直接报错并告诉你正确写法。
五、30 秒上手
pip install tools-registry # 轻量 CLI treg login # 登录你的 treg 账号 treg run --server agentmail-cli inboxes list输出与本地运行一模一样(stdout、stderr、退出码),只是执行体在 1500 公里外。更多细节见 CLI 命令文档、接口文档 与 使用说明。
六、总结:密钥永不到达你机器的 6 层防护
- 📤 客户端只上传工具名与参数,不携带也不持有供应商密钥;
- 🛡️ 二进制白名单 + 成员权限 + 工具 ACL + deny 规则 + 每日额度,层层拦截;
- 🧹 净化环境:子进程不继承服务端机密,密钥只注入指定变量;
- 🏠 一次性 HOME + 独立进程组 + CPU/文件大小/core dump 资源限额;
- 💀 结束(含正常结束)即整组击杀 + 删除临时 HOME + 输出密钥脱敏;
- 📋 每次运行全量审计,
treg runs可回查。
这就是 treg 作为“agent 工具的 OpenRouter”敢做出“密钥永不到达你机器”承诺的工程基础:不靠信任,靠隔离。
【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址: https://gitcode.com/GitHub_Trending/treg/treg
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考