Appearance
工具权限沙箱专题
版本:
v1.1最后更新:
2026-07-07适用对象:需要为 Agent、工作流、MCP 工具、外部写操作和多租户系统设计工具权限边界、审批机制、执行隔离和审计能力的产品、平台、安全与工程同学
Agent 一旦从“只输出文本”走向“能调用工具”,风险模型就会发生本质变化。
- 说错了,通常是回答质量差
- 调错了,可能真的改数据、发消息、触发外部动作
- 权限给大了,可能越权读写别人的数据
- 工具边界做松了,可能把系统提示词里的限制直接绕过去
这也是为什么很多团队做 Agent 时,最先暴露出来的不是模型能力问题,而是工具边界问题。
OpenAI 在 Agents、Using tools、Guardrails and human review、MCP/Connectors 和 Sandbox agents 文档里都把一个核心原则说得很明确:
- 模型可以建议调用什么工具
- 但系统必须决定它真正能调用什么、以什么权限调用、在哪个执行边界里调用、何时必须停下来让人确认
一句话说,工具权限沙箱不是“给工具加个提示词”,而是:
把工具访问、参数范围、执行环境、审批节点和审计记录做成强机制
1. 什么是工具权限沙箱
更实用的理解通常是:
- 让模型调用工具时始终处在被限制、可审计、可暂停、可回收、可隔离的执行边界里
它至少要回答五个问题:
| 问题 | 说明 |
|---|---|
| 能调什么 | 哪些工具对当前 Agent、当前任务、当前用户可见 |
| 能看什么 | 哪些数据、租户、目录、API 范围允许访问 |
| 能写什么 | 哪些动作允许执行,哪些必须审批,哪些永远禁止 |
| 在哪里调 | 是在受限容器、受限进程、远端执行器还是浏览器环境里执行 |
| 事后怎么看 | 是否能追溯调用主体、参数、结果、审批链路和失败原因 |
所以沙箱不是单一技术点,而是一整套控制系统。
2. 为什么工具层风险比文本层高很多
文本输出很多时候只是建议,工具调用却会触发真实副作用。
常见副作用包括:
- 查询企业内部数据
- 修改数据库记录
- 写文件、删文件、上传文件
- 发邮件、发 IM、发工单
- 触发审批、退款、采购、发布、下单
- 控制浏览器、终端、远端容器或桌面
一旦工具层失控,风险往往比普通幻觉更直接:
- 数据泄露
- 越权读写
- 误操作
- 审批绕过
- 对外误发送
- 资金或业务损失
Anthropic 在 computer use 文档里也明确提醒,允许模型操作计算环境会显著提升能力,同时也会引入新的安全风险,因此必须加限制、加监控、加人工确认。
3. 为什么不能只靠提示词约束
很多系统一开始会这样做:
- 在 system prompt 里写“不要调用高风险工具”
- 在工具描述里写“只有必要时才使用”
- 在说明里写“禁止访问其他租户的数据”
这些约束有帮助,但它们不是强边界。
原因很简单:
- 模型可能误判
- 模型可能被用户提示注入影响
- 模型可能在复杂链路里忘记约束
- 工具描述和系统规则本身也会被长上下文稀释
OpenAI 的 safety-in-building-agents 与 guardrails/human-review 文档,都强调安全边界应该落在系统机制上,而不是只落在自然语言约束上。
真正稳妥的做法通常是:
- 工具注册白名单
- 参数 schema 校验
- 执行前权限复核
- 高风险动作审批
- 独立执行环境
- 审计和回放
也就是说:
- 提示词只能表达策略
- 沙箱机制才负责强制执行策略
4. 工具权限沙箱到底在保护什么
更完整的威胁模型通常包括四层。
4.1 数据边界
防止模型读到不该读的数据:
- 其他租户数据
- 其他用户文件
- 内部密钥
- 敏感配置
- 高权限日志
4.2 动作边界
防止模型执行不该执行的动作:
- 删除
- 发布
- 发消息
- 批量修改
- 支付
- 调高风险 API
4.3 资源边界
防止模型滥用系统资源:
- 无限检索
- 无限重试
- 超长运行
- 超额网络访问
- 过量磁盘和内存占用
4.4 信任边界
防止模型借工具跳出原本的控制面:
- 借浏览器执行未审查动作
- 借终端拿到更高权限
- 借 MCP 访问未经明确授权的数据源
- 借“代理工具”再去调用更多下级工具
工具沙箱设计的目的,就是把这四类边界都落到系统里。
5. 一个更实用的架构视角
可以把工具权限沙箱拆成五层。
5.1 暴露层
决定哪些工具出现在模型可见的 tool list 里。
5.2 决策层
模型决定是否尝试调用工具、要传哪些参数。
5.3 策略层
系统判断:
- 当前主体是否允许调这个工具
- 这些参数是否合法
- 是否需要审批
- 是否必须降级或拒绝
5.4 执行层
工具在受限环境里真正执行。
5.5 审计层
记录调用主体、上下文、审批记录、结果和副作用。
把这五层拆开有一个好处:
- 就算模型想错了,后面仍然有多个机制可以把风险挡住
6. 一个工具不是一个权限,至少要拆成多个维度
很多团队会把权限简化成:
text
能不能调用这个工具这通常不够。
更稳妥的权限模型至少要包括:
| 维度 | 示例 |
|---|---|
| 工具级权限 | 是否能调用 crm_update |
| 数据范围 | 只能访问本租户、本用户、本项目 |
| 动作级权限 | 只读、草稿、写入、删除、发送 |
| 参数范围 | 只能更新某些字段,金额上限是多少 |
| 次数预算 | 单任务最多调几次 |
| 时间窗口 | 临时授权 10 分钟有效 |
| 审批要求 | 某些动作必须 human approval |
| 环境边界 | 只能在受限容器里执行 |
如果只有“可调/不可调”两个状态,就很难支撑生产环境。
7. 一个更实用的工具风险分层
工具分层是最基础也最重要的一步。
7.1 只读工具
典型例子:
- 搜索
- 检索
- 查询订单状态
- 读取知识库
- 读取仪表盘指标
主要风险:
- 越权读取
- 泄露敏感数据
- 过量查询
7.2 低风险写工具
典型例子:
- 生成草稿
- 写临时记录
- 创建待审核条目
- 给 CRM 添加内部备注
主要风险:
- 错写
- 写入错误位置
- 垃圾数据污染
7.3 中风险业务工具
典型例子:
- 创建工单
- 修改非核心业务字段
- 更新标签
- 发送内部通知
主要风险:
- 误通知
- 跨团队误操作
- 流程推进错误
7.4 高风险执行工具
典型例子:
- 删除数据
- 对外发消息
- 发起退款
- 发布内容
- 修改权限
- 批量变更
主要风险:
- 不可逆损失
- 审批绕过
- 财务和合规事故
分层之后,审批和沙箱策略才真正有了抓手。
8. 工具暴露层要做什么
模型根本不应该看见所有工具。
OpenAI Using tools 和 MCP/Connectors 文档都强调,工具集合本身就是系统设计的一部分。
更好的做法通常是:
- 按任务类型暴露最小工具集
- 按用户角色过滤工具
- 按租户配置过滤工具
- 按执行阶段动态暴露工具
例如:
json
{
"task_type": "refund_review",
"visible_tools": [
"search_policy",
"query_order",
"draft_approval_summary"
],
"hidden_tools": [
"issue_refund_payment",
"delete_order",
"grant_admin_role"
]
}工具不暴露给模型,往往比暴露后再靠 prompt 约束更可靠。
9. 参数 schema 不只是工程便利,也是安全边界
OpenAI structured outputs 和 using tools 文档都体现了同一个思路:
- 工具参数越结构化,系统越容易校验,也越容易阻止危险动作
一个好的工具 schema 应尽量做到:
- 字段明确
- 枚举值明确
- 必填字段明确
- 长度范围明确
- 数值范围明确
- 默认值明确
例如:
json
{
"name": "update_customer_note",
"parameters": {
"type": "object",
"properties": {
"tenant_id": { "type": "string" },
"customer_id": { "type": "string" },
"note_type": {
"type": "string",
"enum": ["internal", "draft"]
},
"content": {
"type": "string",
"maxLength": 1000
}
},
"required": ["tenant_id", "customer_id", "note_type", "content"],
"additionalProperties": false
}
}这样的 schema 至少能拦住:
- 未知字段
- 超长输入
- 未声明动作类型
- 非法枚举
10. 参数校验要在执行前做第二层策略复核
schema 合法不等于业务上就允许执行。
例如:
customer_id存在,但不属于当前租户amount合法,但超过当前用户额度note_type合法,但当前场景不允许写email合法,但这是外部地址,需要审批
所以执行前还需要业务策略引擎再查一层:
json
{
"tool": "issue_refund",
"actor_role": "support_agent",
"tenant_id": "t_001",
"policy_checks": [
"order_belongs_to_tenant",
"refund_amount_under_limit",
"approval_exists_if_amount_gt_5000",
"customer_status_not_blacklisted"
]
}更实用的理解是:
- schema 解决“格式对不对”
- policy 解决“这次该不该做”
这两层不能互相替代。
11. 批准机制是工具沙箱的一部分,不是外围补丁
OpenAI Guardrails and human review 与 Node reference 里的人审节点和 approval 节点说明得很直接:
- 某些工具动作天生就不应该由模型单独完成
更稳妥的审批设计通常包括三类。
11.1 显式审批
高风险动作必须先出审批卡片,再允许执行:
- 发邮件
- 退款
- 批量更新
- 改权限
11.2 二次确认
中风险动作需要用户确认:
- 是否真的发送
- 是否真的覆盖原值
- 是否继续高成本外部调用
11.3 人工接管
复杂或模糊情况直接转人工:
- 权限冲突
- 数据不一致
- 高价值客户投诉
- 不可恢复错误
审批不是降低能力,而是把高风险动作从“模型直接做”改成“模型准备,人类拍板”。
12. 执行环境沙箱要和 orchestration 分开看
OpenAI Sandbox agents 的价值就在这里:
- 规划与编排可以在 Agent runtime 里做
- 但真正执行高风险工具或代码,不一定要在同一个信任边界里做
很多工具其实需要单独受限执行环境,例如:
- 代码运行
- 浏览器自动化
- 文件转换
- shell / terminal
- 抓网页
- 运行第三方脚本
如果这些执行直接共享主业务服务的高权限环境,风险会很高。
更稳妥的做法通常是把工具执行放进:
- 受限容器
- 受限进程
- 只读文件系统
- 出网受限网络
- 短生命周期运行环境
模型本身不需要拿到宿主环境的全部能力。
13. 对执行环境通常要限制什么
13.1 文件系统
- 只允许访问工作目录
- 区分只读和可写目录
- 禁止访问宿主敏感路径
- 限制上传与下载目录
13.2 网络
- 限制出站域名或 IP
- 阻止访问内网元数据地址
- 阻止访问未经登记的第三方端点
- 限制长连接和扫描式访问
13.3 进程能力
- 限制可执行命令
- 限制子进程数量
- 限制 CPU、内存、磁盘
- 限制最长运行时长
13.4 凭证
- 不把主系统长期密钥直接暴露给工具
- 优先使用短时令牌
- 按工具、按租户、按会话单独发放
这些限制共同构成执行层沙箱。
14. 凭证设计是最容易被忽略的一层
很多工具沙箱表面做得不错,但最后还是因为凭证设计太粗而失效。
常见坏味道包括:
- 把全局 API Key 直接给所有工具
- 多个租户复用同一后台凭证
- 令牌不区分读写范围
- 会话结束后凭证不回收
更稳妥的做法通常是:
- 短生命周期凭证
- 最小 scope
- 租户隔离
- 用户代理授权
- 每次工具调用可追溯到主体
例如:
json
{
"credential": "ephemeral_token",
"scope": ["crm.note.write"],
"tenant_id": "t_001",
"user_id": "u_123",
"expires_in_seconds": 600
}如果凭证本身没有边界,工具沙箱往往只是看起来有边界。
15. 多租户系统里,工具权限必须绑定主体
如果系统服务多个团队、多个客户或多个租户,沙箱不能只看“这个 Agent 能不能调工具”,还要看:
- 这个 Agent 代表谁调工具
- 它现在在哪个租户边界内调工具
- 工具访问的资源是否真的属于这个边界
也就是说,工具执行上下文至少应该显式带上:
tenant_iduser_idsession_idactor_roledelegated_scope
否则会出现非常危险的情况:
- 同一个工具对所有租户共用一个管理员身份
- 同一个 session 里越权读到了别的客户记录
- 日志里根本追不出是谁发起的
多租户隔离不是部署问题,它也是工具权限问题。
16. MCP 和连接器把工具边界问题放大了
OpenAI MCP and Connectors 文档说明,远程工具和数据源接入能显著扩展 Agent 的能力,但同时也会把信任边界拉长。
原因在于:
- 工具可能不在你自己的进程里
- 数据可能来自远端系统
- 模型看到的是“工具接口”,看不到后面的真实 blast radius
这时需要额外考虑:
- 远端 MCP server 的权限范围
- 工具元数据是否足够清晰
- 是否对 destructive action 做了清楚标注
- 是否需要默认审批
- 是否有连接器级别的访问审计
一个成熟的 MCP 工具接入流程,至少要包含:
- 工具清单审核
- schema 审核
- 权限范围审核
- 风险等级标注
- 审批策略绑定
- 观测与日志接入
不要因为“它只是一个 connector”就把它当低风险。
17. Client-side 工具和 Server-side 工具风险不一样
工具不都是同一种执行模型。
17.1 Server-side 工具
特点:
- 系统在服务端执行
- 更容易统一做审计和权限控制
风险:
- 一旦凭证和边界做错,影响面更大
17.2 Client-side 工具
特点:
- 在用户浏览器、桌面或本地环境执行
- 往往能访问更贴近用户的数据和界面
风险:
- 容易碰到本地文件、浏览器状态、登录态
- 更需要显式授权和可视化确认
Anthropic 的 computer use 和 OpenAI 的高权限 agent/runtime 场景都说明一个现实:
- 当工具能操作真实界面和本地资源时,必须把审批、观察和停止能力做得更强
18. 工具结果也需要降权回传
很多系统只在“发请求前”做权限控制,却忽略“结果回来后”也可能有问题。
例如:
- 工具返回了过量敏感字段
- 工具返回了其他租户的内容
- 工具返回了不该进入对话上下文的 secret
- 工具返回了可以诱导下一步危险动作的未审查文本
更稳妥的做法是:
- 对工具输出再做过滤和脱敏
- 只把需要的字段送回模型
- 不把原始敏感负载整段灌回上下文
也就是说,沙箱不只是“限制输入”,也要“限制返回”。
19. 为什么日志和回放是沙箱的一部分
如果工具调用完了却看不见发生了什么,安全边界几乎等于不存在。
建议记录的字段至少包括:
json
{
"request_id": "req_001",
"session_id": "sess_001",
"tenant_id": "t_001",
"user_id": "u_123",
"agent_id": "agent_support_v2",
"tool": "issue_refund",
"risk_level": "high",
"input_summary": "refund amount 6200",
"policy_decision": "approval_required",
"approval_id": "appr_009",
"execution_env": "sandbox_container",
"result": "blocked_until_approval"
}重点是要能回答:
- 谁发起的
- 用了哪个工具
- 传了什么参数
- 触发了什么策略
- 是否经过审批
- 在哪个环境里执行
- 最终发生了什么
没有这些字段,就很难追责、复盘和修规则。
20. 一个更实用的策略引擎示例
json
{
"tool": "send_email",
"actor_role": "support_agent",
"rules": [
{
"if": "recipient_domain not in tenant_allowlist",
"action": "deny"
},
{
"if": "message_type == 'external'",
"action": "require_human_approval"
},
{
"if": "contains_sensitive_attachment == true",
"action": "deny"
},
{
"if": "draft_only == true",
"action": "allow_as_draft"
}
]
}这种策略有几个优点:
- 能细分 allow / deny / require_approval / draft_only
- 能把风险规则和业务规则写清楚
- 能给日志留下结构化决策结果
比起“让模型自己判断是不是该发”,这类机制稳定得多。
21. 工具权限沙箱要怎样进入评测体系
这类能力不能只靠安全同学审文档。
它也要进入评测集和回归体系。
21.1 离线评测样例
应覆盖:
- 正常只读场景
- 越权读取尝试
- 跨租户访问尝试
- 高风险写操作审批场景
- 参数越界场景
- 长时间运行与重复调用场景
21.2 关键评测指标
| 指标 | 说明 |
|---|---|
| unauthorized_tool_exposure_rate | 不该暴露的工具被暴露的比例 |
| policy_block_rate | 被策略正确拦截的比例 |
| approval_trigger_recall | 应触发审批时是否真的触发 |
| cross_tenant_leak_rate | 跨租户泄露率 |
| secret_return_rate | 工具返回敏感信息的比例 |
| unsafe_write_bypass_rate | 高风险写操作绕过审批的比例 |
21.3 线上观测指标
| 指标 | 用途 |
|---|---|
| tool_calls_by_risk_level | 高风险工具使用情况 |
| approval_required_rate | 审批触发是否异常变化 |
| approval_bypass_rate | 是否存在绕过审批迹象 |
| denied_tool_rate | 是否持续尝试违规工具 |
| token_after_tool_result | 工具结果是否带来过量上下文膨胀 |
沙箱做得再漂亮,如果没有评测和监控,也很难长期稳定。
22. 工具权限沙箱和回合控制是联动关系
工具权限越大,回合控制越重要。
因为危险不只是“能不能调”,还包括:
- 调多少次
- 重试多少次
- 在什么阶段调
- 失败后是否继续盲试
例如:
- 低风险读工具可以允许多次
- 高风险写工具可能只允许一次,并且必须审批
- 对外消息工具可能失败后不允许自动重试
所以工具权限策略应该和 Agent回合控制专题 配套设计。
23. 常见失败模式
23.1 默认全开
表现:
- 所有工具对所有 Agent 默认开放
后果:
- 模型一旦误判,伤害面直接最大化
23.2 只有工具级权限,没有数据级边界
表现:
- 虽然只开放了一个
query_customer,但没限制 tenant scope
后果:
- 越权读取
23.3 高风险动作和低风险动作走同一链路
表现:
search_policy和issue_refund使用完全一样的授权流程
后果:
- 高风险动作没有额外保护
23.4 只校验格式,不校验业务规则
表现:
- 参数 JSON 合法就执行
后果:
- 额度越界、审批缺失、状态不符仍然被执行
23.5 执行环境和主系统共用高权限
表现:
- shell、浏览器、代码执行都跑在主服务权限下
后果:
- 一次工具失控可能扩大为系统级风险
23.6 日志只记“调用成功/失败”
表现:
- 没有主体、策略、审批和参数摘要
后果:
- 出事后无法复盘
24. 优化工具权限沙箱的常见手段
24.1 最小暴露
- 每个任务只暴露必要工具
- 每个阶段只暴露当前步骤需要的工具
24.2 最小权限
- 读写拆开
- 租户范围拆开
- 字段范围拆开
- 额度范围拆开
24.3 最小凭证
- 用短时 token
- 让 token 和主体绑定
- 不要给工具全局管理员密钥
24.4 最小执行环境
- 只给必需的文件、网络和进程能力
- 高风险执行放到独立 sandbox
24.5 人工审核前置
- 让模型生成草稿和建议
- 让人批准最终动作
这通常比一味“禁止工具”更实用。
25. 一个可执行的落地流程
25.1 先盘点工具清单
列出所有:
- 读工具
- 写工具
- 对外工具
- 浏览器和 shell 类工具
- 第三方连接器
25.2 给每个工具定风险等级
至少区分:
- low
- medium
- high
- destructive
25.3 给每个工具定义 schema 和 policy
包括:
- 参数结构
- 租户范围
- 次数限制
- 审批要求
- 输出过滤规则
25.4 设计执行环境
确认:
- 是否需要独立容器
- 是否限制出网
- 是否只读文件系统
- 是否需要短时凭证
25.5 接入日志和回放
要能追溯:
- 看到的工具
- 实际调用的工具
- 被拒绝的原因
- 被审批的链路
25.6 做回归评测
至少跑:
- 越权读取
- 参数越界
- 跨租户访问
- 高风险动作审批
- 工具输出脱敏
这样工具权限沙箱才算真正落地。
26. 推荐搭配阅读
27. 落地检查清单
- 是否按任务和角色动态暴露最小工具集?
- 是否对工具同时做工具级、数据级、动作级和参数级控制?
- 是否把 schema 校验和业务 policy 校验分成两层?
- 是否对高风险动作接入审批、确认或人工接管?
- 是否把高风险执行放进独立受限环境,而不是共用主服务高权限?
- 是否给工具使用短时、最小 scope、与主体绑定的凭证?
- 是否对 MCP / connector 工具单独做风险审核和默认审批策略?
- 是否对工具输出做脱敏和字段级过滤,而不是原样塞回模型上下文?
- 是否记录调用主体、策略决策、审批链路、执行环境和结果?
- 是否把越权读取、跨租户访问、审批绕过等场景纳入回归评测?
28. 推荐资源
以下资源在 2026-07-07 检查时可访问,适合作为工具权限沙箱、审批、执行边界和连接器风险的官方参考。
OpenAI
- Agents guide:https://developers.openai.com/api/docs/guides/agents
- Using tools:https://developers.openai.com/api/docs/guides/tools
- Structured outputs:https://developers.openai.com/api/docs/guides/structured-outputs
- Guardrails and human review:https://developers.openai.com/api/docs/guides/agents/guardrails-approvals
- MCP and Connectors:https://developers.openai.com/api/docs/guides/tools-connectors-mcp
- Sandbox agents:https://developers.openai.com/api/docs/guides/agents/sandboxes
- Safety best practices:https://developers.openai.com/api/docs/guides/safety-best-practices
- Node reference:https://developers.openai.com/api/docs/guides/node-reference
- Evaluate agent workflows:https://developers.openai.com/api/docs/guides/agent-evals
- Trace grading:https://developers.openai.com/api/docs/guides/trace-grading
Anthropic
- Tool use overview:https://docs.anthropic.com/en/docs/agents-and-tools/tool-use/overview
- Computer use:https://docs.anthropic.com/en/docs/agents-and-tools/computer-use
LangGraph / LangChain
- Interrupts:https://docs.langchain.com/oss/python/langgraph/interrupts
- Human-in-the-loop:https://docs.langchain.com/oss/python/langchain/human-in-the-loop
- Middleware overview:https://docs.langchain.com/oss/python/langchain/middleware/overview
29. 最后总结
工具权限沙箱不是一个附属安全功能,而是 Agent 系统能否进入生产环境的基础设施。
它真正要解决的,不只是“模型会不会乱调工具”,而是:
- 模型到底能看见哪些工具
- 这些工具能以什么权限访问什么数据
- 哪些动作必须审批
- 工具在什么执行边界里运行
- 调用后如何审计、回放和追责
如果这些问题没有被机制化,系统很容易陷入一种危险错觉:
- 模型看起来很聪明
- 但工具一旦走错一步,后果就比普通回答错误严重得多
更成熟的做法,是把工具暴露、参数校验、业务 policy、审批、人机协同、执行环境隔离和评测监控串成一条完整链路。
这样模型就不是“拿着万能钥匙瞎试”,而是在明确边界内被授予有限且可追溯的行动能力。