从RBAC到三层动态裁剪:企业级Agent平台的权限模型设计

SailTrack
2026-05-09
点 赞
1
热 度
4
评 论
0
  1. 首页
  2. 后端开发
  3. 从RBAC到三层动态裁剪:企业级Agent平台的权限模型设计

一、为什么传统RBAC不够用了?——从打卡平台到Agent平台

讲权限模型之前,先交代一下这个项目的来历。

Workforce Hub 最开始不是我主动要做的。上学期期末设计,我做了一个「员工智能打卡平台」,就是那种前端调摄像头拍照打卡、后端存记录的常规系统。当时觉得做完就完了,没想到这学期开学,老师找到我,问愿不愿意进他的课题组。

老师说我的打卡平台可以继续优化,做好了能当毕设。我一想,那挺好,就开干了。结果越改越收不住——加了排班管理、假期审批、即时消息……项目体量越来越大,早就不止打卡一个功能了。

这时候我去找老师聊,老师说了一句话让我印象很深:"你这个技术栈是传统的堆叠,可以结合当下的 AI 功能,做一些差异化的东西。"然后他推荐我申报学校的大学生创新训练计划,也就是现在的 Workforce Hub。

后面的路由就得自己走了——查资料、问 AI、啃 Spring AI 的文档、研究 Agent 的工作机制。就是在设计 Agent 权限的时候,我遇到了一个绕不过去的问题:

Agent 替用户干活的时候,它能调用哪些能力?能访问哪些数据?

举个例子:员工小张请了一天假,他告诉 Agent"帮我提交请假申请"。这个 Agent 需要:

  • 调用工作流引擎的"创建审批"接口

  • 读取小张的假期余额

  • 查看部门排班信息来判断是否有冲突

但问题来了——这个 Agent 是小张的 Agent,它不能

  • 直接批准请假(那得部门主管批)

  • 查看其他同事的假期余额(隐私数据)

  • 修改考勤规则(管理员才有的权限)

传统 RBAC 只能回答"用户能做什么",没法回答"Agent 替用户能做什么"。因为 Agent 不是一个用户——它是一个运行中的程序,有自己能力清单,却又受限于启动它的那个用户的授权范围。

这就是我设计三层权限裁剪模型的起点。

二、三层权限裁剪:三个集合求交集

核心思路一句话就能说清楚:

Agent 最终能做的事 = Agent 能力 ∩ 用户授权 ∩ 数据可见域

每次 Agent 执行任务,都动态计算这三个集合的交集。不是一次性配置好的静态权限,而是运行时实时裁剪

下面逐层拆开讲。

2.1 第一层:Agent 自身的能力边界

每个 Agent 注册时就要声明自己能干什么。在 Workforce Hub 里,Agent 的能力是一组工具(Tool) 的集合:

Agent "员工助理" 的能力清单:
├── workflow:create_approval    # 发起审批
├── workflow:query_status       # 查询审批状态
├── leave:query_balance         # 查假期余额
├── attendance:query_schedule   # 查排班信息
├── im:send_message             # 发消息
└── kb:search_document          # 搜知识库

注意这个 Agent 没有 workflow:approveattendance:update_rule——这些是管理员 Agent 才有的能力。

我的理解:Agent 能力的"最小化原则"。只给它完成本职工作需要的工具,多一个都不给。这样做的好处是:即使后续两层权限出了问题(比如用户授权配错了),Agent 本身的能力天花板也在那里,不会捅出超范围的篓子。

2.2 第二层:用户授权的范围

这就是我们熟悉的 RBAC 部分。在 Workforce Hub 里,用户-角色-权限的关系如下:

角色

典型权限

普通员工

查看个人考勤、申请假期、发起审批

部门主管

审批本部门请假、查看部门排班、分配任务

HR

管理员工信息、配置假期规则、查看全公司考勤报表

系统管理员

管理角色权限、配置 Agent、管理知识库

当员工小张通过 Agent 发起操作时,系统先查:小张本人有这个权限吗? 如果没有,Agent 也不能替他干。

血泪教训:我一开始写权限校验的时候偷懒,Agent 调用服务时直接绕过用户权限检查,让 Agent 以系统身份执行。结果测试时发现 Agent 能替普通员工查全公司考勤数据——因为服务层没做用户级别的权限校验。后来全部加上了 @PreAuthorize 注解才堵上这个洞。

2.3 第三层:业务数据的可见域

这一层最容易被忽略,但恰恰是 Agent 场景下最关键的。

举个例子:部门主管老王的 Agent 有 attendance:query_report 权限,但这不代表它能查全公司的考勤数据——它只能查老王管辖的部门。

在 Workforce Hub 里,数据可见域的定义包括:

维度

说明

示例

组织范围

能访问哪些部门的数据

本部门 + 下级部门

时间范围

能访问多久以前的数据

最近 3 个月

字段级别

能看到哪些字段

考勤状态 ❌ 不可见,出勤天数 ✅ 可见

知识域

能检索哪些知识库

技术文档 ✅,HR 内部文档 ❌

这其实就是 ABAC(基于属性的访问控制) 在 Agent 场景的延伸。不同的是,传统 ABAC 的规则是静态配置的,而 Agent 的数据域需要与另外两层动态交互。

2.4 动态裁剪:运行时求交集

三层权限的关系不是叠加,是求交集。用伪代码表示:

// Agent 每次执行操作时的权限裁剪逻辑
public Set<String> getEffectivePermissions(Agent agent, User user, String action) {
    // 第一层:Agent 注册的能力
    Set<String> agentCapabilities = agent.getTools();
    
    // 第二层:用户拥有的权限
    Set<String> userPermissions = permissionService.getUserPermissions(user);
    
    // 第三层:用户对目标数据的可见域
    DataScope dataScope = dataScopeService.getScope(user, action);
    
    // 三层求交集
    Set<String> effective = new HashSet<>(agentCapabilities);
    effective.retainAll(userPermissions);        // ∩ 用户权限
    effective.retainAll(dataScope.getAllowed());  // ∩ 数据可见域
    
    return effective;  // 最终允许的操作
}

关键要点:这个计算发生在每次 Agent 调用工具时,不是登录时算一次就缓存住。因为用户权限和数据域可能在会话期间发生变化(比如临时授权过期、角色调整)。

三、与传统权限模型的对比

为了做出合适的选择,我在设计阶段对比了几个常见的权限方案:

维度

传统RBAC

RBAC+ABAC

三层动态裁剪(本项目)

权限主体

用户

用户 + 属性

Agent + 用户 + 数据域

计算时机

登录时

访问时

每次工具调用时

Agent支持

❌ 无

❌ 无

✅ 原生支持

数据行级控制

复杂度

中高

适用场景

传统Web应用

数据安全等级高的系统

Agent驱动的协作平台

传统 RBAC 像给每个人发一张通行证,写了能进哪些门。三层裁剪模型像一个保安——每次进门都重新核对你、你的陪同人(Agent)、你今天要进哪个房间,三个条件都满足才放行。

四、实现中的几个关键决策

4.1 权限检查放在哪一层?

这是个让架构师吵翻天的问题。有人说放网关(统一入口,好维护),有人说放 Service 层(贴近业务,灵活)。

我的选择是:两层都放

  • 网关层:做粗粒度检查(“这个 Agent 有没有被禁用?”),快速拦截

  • Service 层:做细粒度检查(“这个用户能不能对这个部门的这条数据执行这个操作?”),精确裁剪

// Service 层的典型写法
@PreAuthorize("@permissionEvaluator.canAccess(#request)")
public ApprovalResult createApproval(ApprovalRequest request) {
    // 权限校验由 @PreAuthorize 在方法调用前自动完成
    // 业务逻辑...
}

4.2 权限规则放代码还是数据库?

这也是一个经典的选择题。我的方案是:

  • 粗粒度规则(角色-权限绑定)→ 放数据库,支持运行时调整

  • 细粒度规则(数据域、字段级)→ 放代码 + 配置文件,因为和业务逻辑耦合太紧,做成配置项反而容易出错

说实话,这不是什么创新做法,算是一个中规中矩但稳定可靠的选择。

4.3 权限变更的实时生效

如果管理员临时撤销了某个用户的审批权限,Agent 的下一次工具调用就应该立即感知到,不能等到用户重新登录。

Workforce Hub 的做法是:权限查询不走缓存,每次调用都实时查库。代价是多了几次数据库查询,但换来了权限变更的秒级生效。对于企业协同场景,这个取舍是值得的。

五、总结

核心收获

  • Agent 权限不是用户权限的简单复制——它多了一个"能力边界"维度,必须独立建模

  • 三层裁剪的本质是运行时动态求交集,而不是静态配置一张权限表

  • 数据域(第三层)是最容易被忽略但恰恰最关键的——它决定了 Agent 能看到什么、操作什么

  • 权限检查要分层:网关做粗筛、Service 做精细裁剪,两者缺一不可

下一步计划

  • 完善 Agent 工具的风险等级分级(只读/写入/管理),不同风险等级有不同的审批策略

  • 引入权限变更审计日志,记录每次权限裁剪的计算过程

  • 对接 Spring AI 的 ToolCallback 机制,让 Agent 自动感知权限变更

个人感悟:权限模型设计这事,如果只是照着 RBAC 建几张表确实不难——但一旦系统里有了 Agent,问题就从"用户能做什么"变成了"Agent 替用户能做什么",多了一个维度,复杂度直接翻倍。这个过程让我意识到,做系统设计不能只套模板,得从业务场景倒推,想清楚了再动手。


让我们忠于理想,让我们面对显示

SailTrack

entp 辩论家

站长

具有版权性

请您在转载、复制时注明本文 作者、链接及内容来源信息。 若涉及转载第三方内容,还需一同注明。

具有时效性

目录

欢迎来到SailTrack的站点,为您导航全站动态

28 文章数
11 分类数
3 评论数
17标签数