云计算百科
云计算领域专业知识百科平台

从工具不可见到数据不越权:AgentScope工具权限的三层防线

在这里插入图片描述

从工具不可见到数据不越权:AgentScope工具权限的三层防线

AgentScope 工具权限的三层防线

前置阅读:《若依框架和阿里 AgentScope 的权限封装》

上一篇主要讨论如何把若依的角色权限接入 Agent 工具体系,重点解决“无权限用户不应该在模型上下文中看到 Tool Schema”,以及为什么不能只依赖工具执行阶段的 @PreAuthorize。本文继续向下拆解,给出一套覆盖工具可见性、调用决策和业务数据范围的三层权限模型。

一、为什么 Agent 工具权限不能只做一次校验

传统 Web 接口的权限控制通常发生在 Controller 或 Service 执行之前:

@PreAuthorize("@ss.hasPermission('inventory:stock:query')")

但 Agent 的执行链路比普通 HTTP 请求更长:

用户问题
→ Agent 获取 Tool Schema
→ 大模型选择工具
→ Agent 发起 Tool Call
→ Java 工具方法执行
→ Service 查询业务数据
→ 结果返回大模型

如果只在 Java 方法执行前校验权限,会留下三个不同的问题:

  • 用户没有工具权限,但模型已经看到了工具名称、描述和参数结构。
  • 用户可以使用工具,但某次调用属于高风险操作,需要动态拒绝或人工确认。
  • 两个角色都能调用同一个查询工具,但能够读取的数据范围不同。
  • 这三个问题对应三个不同的安全边界,不能用一个注解或一次拦截全部替代。

    二、三层权限模型

    一套完整的 Agent 工具权限体系,可以拆分为以下三层:

    层级核心问题控制时机典型结果
    第一层:工具可见性 这个角色对应的 Agent 是否拥有该工具 Tool Schema 发送给模型之前 保留或移除 Tool Schema
    第二层:调用决策 当前这一次工具调用是否允许执行 每次 Tool Call 执行之前 ALLOW、DENY、ASK
    第三层:数据权限 工具执行后允许访问哪些业务数据 Service、Mapper 或查询条件构建阶段 本人、本地区、本部门或跨区域数据

    三层权限分别保护不同对象:

    第一层保护模型上下文
    第二层保护工具执行入口
    第三层保护真实业务数据

    三、第一层:角色与 Agent 的工具可见性

    第一层解决的是:

    当前角色对应的 Agent,究竟应不应该拥有这个工具?

    假设系统中存在三个工具:

    query_inventory 查询库存
    allocate_spare_part 调拨配件
    delete_maintenance 删除维修记录

    普通维修工可能只拥有 query_inventory,区域管理员拥有查询和调拨工具,系统管理员才拥有删除工具。

    在模型推理之前,应根据当前用户的角色与权限生成本轮可见工具集合:

    普通维修工:
    query_inventory

    区域管理员:
    query_inventory
    allocate_spare_part

    系统管理员:
    query_inventory
    allocate_spare_part
    delete_maintenance

    没有授权的工具不仅不能执行,而且不应该把以下内容发送给模型:

    • 工具名称;
    • 工具用途描述;
    • 参数名称;
    • 参数 JSON Schema;
    • 可能暴露内部业务能力的示例。

    这一层属于“能力披露控制”。它能够减少模型上下文噪声,也能降低提示词注入诱导模型尝试越权工具的风险。

    需要特别注意:隐藏 Tool Schema 不等于完成了全部安全控制。模型不可见只是第一道门,工具执行入口仍然需要独立校验。

    四、第二层:AgentScope Permission System 的调用决策

    AgentScope Java 提供了 io.agentscope.core.permission 权限系统。根据官方文档,Permission System 会拦截 Agent 的每一次工具调用,并返回三种决策之一:

    • ALLOW:允许执行;
    • DENY:拒绝执行;
    • ASK:暂停执行并询问用户是否确认。

    这意味着同一个已经对模型可见的工具,不同调用仍然可以得到不同结果。

    例如,维修工拥有配件调拨工具,但不同参数代表不同风险:

    查询本地区配件库存 → ALLOW
    调拨一个普通配件 → ASK
    跨区域调拨高价值配件 → DENY

    1. Permission System 的三个判断来源

    官方权限系统综合以下三个组件进行决策。

    Rules

    PermissionRule 针对具体工具及调用模式配置 ALLOW、DENY 或 ASK。

    规则可以在 PermissionContextState 中预先配置,也可以在用户确认 ASK 时接受建议规则,动态加入当前权限上下文。

    PermissionContextState permissionContext =
    PermissionContextState.builder()
    .mode(PermissionMode.DEFAULT)
    .addAllowRule(
    "query_inventory",
    new PermissionRule(
    "query_inventory",
    null,
    PermissionBehavior.ALLOW,
    "rolePolicy"))
    .addAskRule(
    "allocate_spare_part",
    new PermissionRule(
    "allocate_spare_part",
    null,
    PermissionBehavior.ASK,
    "rolePolicy"))
    .addDenyRule(
    "delete_maintenance",
    new PermissionRule(
    "delete_maintenance",
    null,
    PermissionBehavior.DENY,
    "rolePolicy"))
    .build();

    这里的 ruleContent 不一定只能匹配工具名称。工具可以通过 matchRule() 对实际调用参数进行匹配,从而实现“同一工具、不同参数、不同决策”。

    Mode

    PermissionMode 决定没有命中显式规则时的默认行为。

    Mode行为适用场景
    DEFAULT 未明确允许的调用进入确认流程 默认安全策略
    ACCEPT_EDITS 自动允许安全范围内的编辑操作 用户在线的开发场景
    EXPLORE 允许只读,拒绝写操作和命令 只读探索、规划
    BYPASS 默认放行,但拒绝规则和危险检查仍有效 完全可信沙箱
    DONT_ASK 将所有 ASK 转换成 DENY 定时任务、无人值守流程

    对于没有实时交互界面的后台任务,不应该让 ASK 无限等待。此时可以使用 DONT_ASK,把需要确认的调用安全降级为拒绝。

    Built-in Checks

    工具还可以通过 ToolBase#checkPermissions,基于本次真实输入进行动态风险分析。

    它适合检查无法仅靠静态角色表达的风险,例如:

    • 操作目标是否属于危险目录;
    • 调拨数量是否超过阈值;
    • 是否涉及高价值配件;
    • 目标设备是否处于锁定状态;
    • 当前调用是否会产生不可逆副作用。

    官方文档强调,工具自身的危险检查属于运行时检查,不应被普通规则或模式绕过。

    2. ASK 不是弹一个确认框那么简单

    ASK 表示 Agent 的本次执行被挂起,系统需要保存:

    • 用户身份;
    • 会话身份;
    • Tool Call 编号;
    • 工具名称;
    • 工具参数;
    • 风险说明;
    • 建议规则;
    • 确认有效期。

    用户确认时,必须恢复原来的调用,而不是重新让模型生成一次工具参数,否则确认的内容和最终执行的内容可能不一致。

    确认页面还应该明确展示:

    准备执行的工具:allocate_spare_part
    调拨配件:智能马桶主控板
    调拨数量:2
    来源区域:华东一区
    目标区域:华东三区
    风险提示:跨区域调拨

    用户确认的是一笔确定的操作,而不是模糊的“是否允许 Agent 继续”。

    五、第三层:工具背后的业务数据权限

    第三层解决的是:

    用户拥有这个工具,也允许执行这次调用,但他最终可以看到哪些数据?

    以库存查询为例,普通维修工和区域管理员都拥有:

    inventory:stock:query

    他们也都可能被 Permission System 判定为 ALLOW,但数据范围并不相同:

    普通维修工:
    只能查询所属地区的库存

    区域管理员:
    可以查询管辖区域内多个地区的库存

    总部管理员:
    可以查询全国库存

    因此,数据权限必须在业务 Service 或数据库查询条件中落实:

    Set<Long> readableRegionIds =
    dataScopeService.getReadableRegionIds(currentUserId);

    return inventoryService.getInventory(
    request.getProductId(),
    readableRegionIds);

    查询条件必须取自服务端可信身份,而不能直接相信大模型生成的 regionId。

    错误方式:

    return inventoryMapper.selectByRegionId(toolRequest.getRegionId());

    正确思路:

    模型传入目标区域
    → 服务端计算当前用户可访问区域
    → 判断目标区域是否在授权集合内
    → 带数据范围条件查询

    即使模型伪造了其他区域编号,也无法越过服务端的数据范围限制。

    六、三层权限如何协同

    以“区域管理员跨区域调拨配件”为例:

    第一层:工具可见性
    区域管理员拥有 allocate_spare_part
    → Tool Schema 可以进入模型上下文

    第二层:调用决策
    当前调用属于跨区域调拨
    → Permission System 返回 ASK
    → 用户确认后才继续

    第三层:数据权限
    校验来源区域和目标区域是否都在管理员管辖范围
    → 在范围内执行
    → 超出范围拒绝

    任何一层失败,都必须停止调用:

    Tool 不可见
    OR Permission = DENY
    OR 用户拒绝 ASK
    OR 数据范围不满足
    → 不执行工具

    七、角色权限矩阵示例

    角色Tool SchemaPermission 决策数据范围
    三方维修工 查询维修手册、查询本人维修单 查询 ALLOW,写操作 DENY 本人被派发的工单
    普通维修工 查询库存、申请配件 查询 ALLOW,申请 ASK 所属地区
    区域管理员 查询库存、配件调拨 查询 ALLOW,跨区调拨 ASK 管辖区域
    总部管理员 全部管理工具 普通操作 ALLOW,高风险操作 ASK 全国
    无人值守任务 仅白名单工具 DONT_ASK,其余拒绝 任务配置的数据范围

    这个矩阵中的三列不能合并:

    • Tool Schema 决定模型“知不知道有这个能力”;
    • Permission 决定本次调用“能不能做、是否要问”;
    • 数据范围决定最终“能操作哪些业务对象”。

    八、工程落地时最容易踩的坑

    1. 只隐藏工具,不校验执行入口

    攻击者可能绕过模型入口直接构造 Tool Call,因此执行阶段仍需权限控制。

    2. 只做 ALLOW / DENY,忽略 ASK

    完全放行和完全拒绝之间需要有人机协同边界。配件调拨、删除记录、批量修改等操作更适合 ASK。

    3. 把数据权限写进 Prompt

    Prompt 只能提示模型,不是安全边界。地区、部门、用户等数据范围必须由后端身份和查询条件决定。

    4. 共享可变权限上下文

    如果 Agent 是单例,不能把某个用户的动态权限直接修改到全局共享 Toolkit 或全局规则集合中,否则并发请求可能串权。

    权限状态至少应按用户和会话隔离:

    (userId, sessionId) → PermissionContextState

    5. ASK 恢复时重新生成参数

    确认前后的工具名称和参数必须一致。建议保存原始 Tool Call,并在确认后恢复执行。

    6. 把 BYPASS 当作生产默认值

    BYPASS 更适合完全可信的隔离环境。生产系统应从最小权限开始,根据明确规则逐步放行。

    九、推荐的安全原则

    可以用一句话概括三层工具权限:

    模型只看见应该看见的工具,每次调用都经过明确决策,工具最终只能访问授权范围内的数据。

    落地时建议遵循:

  • 默认不暴露未授权 Tool Schema。
  • 默认使用安全的 Permission Mode。
  • 高风险写操作优先使用 ASK。
  • 无人值守场景将 ASK 降级为 DENY。
  • 数据权限在 Service 和 SQL 查询中强制执行。
  • 所有身份和数据范围均从服务端可信上下文获取。
  • 记录 ALLOW / DENY / ASK、用户确认和数据范围审计日志。
  • 单例 Agent 下的权限状态必须按用户与会话隔离。
  • 十、总结

    Agent 工具权限不是一个简单的“能不能调用”问题,而是一条完整的安全链路:

    角色与 Agent 工具授权
    → Tool Schema 可见性
    → Permission System 调用决策
    → 用户确认
    → 业务数据权限
    → 审计记录

    第一层让无权限工具不进入模型上下文;第二层使用 AgentScope Permission System 对每次调用执行 ALLOW / DENY / ASK 决策;第三层在真实业务查询中落实地区、部门、用户等数据范围。

    三层共同工作,才能真正实现工具能力最小化、调用过程可控制、业务数据不越权。

    参考资料

  • AgentScope Java:Permission System
  • 若依框架和阿里 AgentScope 的权限封装
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » 从工具不可见到数据不越权:AgentScope工具权限的三层防线
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!