2025年1月29日·阅读约1分钟

内部工具中的 RBAC 与 ABAC:如何选择可扩展的权限

内部工具中的 RBAC 与 ABAC:了解如何使用真实的支持和财务示例以及简单决策矩阵来选择角色、属性和记录级规则。

内部工具中的 RBAC 与 ABAC:如何选择可扩展的权限

为什么内部工具的权限会变得混乱

内部工具通常接近业务中最敏感的部分:客户记录、退款、发票、工资备注、交易金额和内部私有评论。不是所有人都应该看到一切,更少人可以编辑这些内容。

权限通常从简单开始:“Support 可以查看工单”、“Finance 可以批准退款”、“Managers 可以查看团队绩效”。然后组织增长、流程改变,工具就变成了例外的拼凑物。

这种“以后爆炸”的模式很常见:

  • 角色膨胀:你先添加 Support,然后 Support - Senior,再到 Support - EU,再到 Support - EU - Night Shift,直到没人记得每个角色包含什么。
  • 例外堆积:少数人需要“额外的一个权限”,于是一次性开关越来越多。
  • 意外暴露:有人可以查看薪资备注、客户 PII 或收入报表,因为某个页面被复用时没有重新检查访问权限。
  • 工作流破裂:用户可以看到记录但无法执行下一步(或更糟的是,在看不到上下文的情况下可以执行下一步)。
  • 审计痛苦:要回答“谁能批准超过 $1,000 的退款?”时,需要人工挖掘大量信息。

选择 RBAC 或 ABAC 的意义不仅在于锁定界面,而是在新团队、地区和政策出现时仍能让规则易于理解。

一个能长期支撑的权限模型有四个特点:容易解释、易于审查、不易被滥用、且便于快速变更。

通俗解释 RBAC(角色和它们解锁的权限)

RBAC(基于角色的访问控制)是“职位名”方法。用户被赋予一个或多个角色(Support Agent、Admin)。每个角色对应一组固定的可见项和可执行操作。如果两个人拥有相同角色,他们就得到相同的访问权限。

当团队日常操作方式大致相同时,且主要问题是功能级别的:“他们能不能使用这个页面?”或“他们能不能执行这个动作?”时,RBAC 很管用。

示例:支持控制台的角色:

  • Support Agent:查看工单、回复客户、添加内部备注
  • Support Lead:具有 Agent 的所有权限,另可重新分配工单并查看团队指标
  • Admin:管理用户、更改系统设置、编辑权限规则

关键思想是角色映射到职责,而不是具体个人。当职责稳定时,角色也稳定,模型也容易解释。

RBAC 适合的场景:

  • 组织架构清晰(团队、负责人、管理员)
  • 大多数访问决策是“能否使用某个功能?”
  • 新人入职需要可预测(分配角色 X 就完成)
  • 审计很重要(容易列出某个角色能做什么)

当现实变得混乱时,RBAC 就开始吃亏。内部工具会收集例外:某个支持人员可以退款、某个财务用户只看一个地区、承包商能看工单但不能看客户 PII。如果你用创建新角色来解决每个例外,就会产生角色爆炸。

一个实用的信号是:你开始每周添加“特殊角色”。这说明仅靠 RBAC 已经不足。

通俗解释 ABAC(基于属性的规则)

ABAC(基于属性的访问控制)用规则来决定访问,而不仅仅是职位。与其问“Finance 角色能做什么?”,ABAC 会问:“给定这个人是谁、这条记录是什么、以及现在发生了什么,是否允许?”

属性是你已经跟踪的事实。一个规则可能写成:

  • “Support agents 可以查看其所在地区的工单。”
  • “Managers 可以在工作时间内批准 5,000 美元以下的报销。”

大多数 ABAC 系统依赖几类属性:

  • 用户属性:部门、地区、是否为经理
  • 数据属性:记录所有者、工单优先级、发票状态
  • 上下文属性:时间、设备类型、网络位置
  • 动作属性:查看 vs 编辑 vs 导出

具体示例:仅当 (a) 工单优先级不是 critical,(b) 工单分配给该用户,且 (c) 客户地区与其地区匹配时,该支持人员才可编辑工单。这样你就避免为每种组合创建诸如 Support - EU - Noncritical 和 Support - US - Noncritical 的角色。

权衡在于,如果特殊情况不断堆叠,ABAC 也会变得难以推理。几个月后,人们可能再也无法在不阅读长串条件的情况下回答“谁能导出发票?”这样的问题。

一个好的 ABAC 习惯是保持规则少、风格一致、并用通俗名称命名。

记录级访问:大多数错误发生的地方

许多团队把权限当成“你能打开这个页面吗?”那只是第一层。记录级访问回答不同的问题:即便你能打开页面,你被允许看到或更改哪些行?

支持人员和财务分析师可能都能进入客户页面。如果只做屏幕级控制,你有可能让每个人看到所有内容。记录级规则缩小了页面内加载的数据范围。

常见的记录级规则包括:

  • 仅限你的客户(assigned_owner_id = current_user.id
  • 仅限你所在区域(customer.region IN current_user.allowed_regions
  • 仅限你的成本中心(invoice.cost_center_id IN current_user.cost_centers
  • 仅限你团队的工单(ticket.team_id = current_user.team_id
  • 仅限你创建的记录(created_by = current_user.id

记录级访问必须在获取和修改数据的地方强制执行,而不是仅在 UI。实际上,这意味着查询层、API 端点和业务逻辑都要应用这些规则。

典型失败模式是“页面被锁定,但 API 开放”。按钮对非管理员隐藏了,但端点仍返回所有记录。任何能访问应用的人,有时可以通过重用请求或调整过滤器触发该调用。

用几个问题来检验你的模型是否合理:

  • 如果用户直接调用端点,他们是否仍只能拿到被允许的记录?
  • 列表、详情、导出和计数端点是否都应用相同规则?
  • 创建、更新和删除是否分别检查(而不仅仅是读取检查)?
  • 管理员是有意绕过规则,还是意外绕过?

屏幕权限决定谁可以进房间。记录级访问决定他们进房间后能打开哪些抽屉。

真实示例:支持、财务和经理

原型化你的审批工作流
对工单、发票和审批流程建模,创建可以在不重写代码的情况下调整的清晰工作流。
开始构建

目标不是“完美安全”,而是今天人们能理解、以后能更改且不会破坏工作流的权限。

支持团队

支持通常需要记录级规则,因为“所有工单”很少是真实场景。

一个简单模型:座席可以打开并更新分配给自己的工单,以及队列中的任何工单。团队负责人可以重新分配工单并在升级时介入。经理通常需要仪表盘查看但不需要编辑所有工单。

批量操作和导出是常见的变数。很多团队允许批量关闭、限制批量重分配,并只允许负责人和经理导出且记录日志。

财务团队

财务访问主要关乎审批步骤和清晰的审计轨迹。

常见设置:AP 职员可以创建账单并保存草稿,但不能审批或支付。Controller 可以审批并放行付款。审计员应为只读,包括附件,不能更改供应商详情。

现实规则示例:

“AP clerk 可以编辑自己创建的草稿;一旦提交,只有 controller 能修改它。”

这是记录级访问(状态 + 所有者),通常比创建更多角色更适合用 ABAC 实现。

经理

大多数经理需要广泛的可见性但有限的编辑权限。

实用模式:经理可以查看大部分运营数据,但只能编辑其团队拥有或与直接下属相关的记录(例如休假申请、目标、绩效备注)。像 team_idmanager_idemployment_status 这样的属性通常比为每个部门创建单独角色更清晰。

在这些群体中,你通常需要:

  • 支持:按分配/队列可见、谨慎的导出、受控的重新分配
  • 财务:基于状态的规则(草稿 vs 已提交 vs 已审批)、严格审批、审计安全的只读访问
  • 经理:广泛查看、有限编辑(团队拥有或直接下属的记录)

决策矩阵:角色 vs 属性 vs 记录级规则

不要纠结“哪个更好”,而要问权限问题的哪些部分适合哪种模型。大多数团队最后会采用混合:用角色划出大通道,用属性处理例外,用记录级过滤来限定“仅我的内容”。

评估项角色 (RBAC)属性 (ABAC)记录级过滤
团队规模适用于小到中等且岗位职能明确的团队。随着团队增长、职责边界模糊,属性变得有价值。只要归属重要,就需要记录级过滤,无论团队大小。
例外频率当你不断说“除了 Support 的每个人...”时会崩溃。能处理“如果 region = EU 且 tier = contractor 则...”这样的条件而不增加角色数量。处理“仅分配给我的工单”和“仅属于我成本中心的发票”。
审计需求易于解释:“Finance 角色可以导出发票”。如果规则有清晰文档,也能适合审计。往往是审计必需,因为它证明访问被限定到具体数据。
重组风险如果角色紧贴组织结构,风险更高。如果使用稳定属性(department_id、employment_type),风险较低。中等风险:只要归属字段准确,所有权规则能在重组中幸存。

把权限逻辑当作每月账单来看待。每增加一个角色、规则或例外,都要花时间测试、解释和调试。只做最小的工作来覆盖当前真实场景。

一个实用默认:

  • 用 RBAC 开始,划分大通道(Support、Finance、Manager)。
  • 对重复出现的条件(区域、资历、客户等级)添加 ABAC。
  • 当用户应只看到“自己的”条目时,加入记录级规则,而不是把整个表暴露给他们。

逐步指南:在构建界面前设计权限

锁定导出与批量操作
创建列表、明细和导出流程,确保每次都应用相同的访问规则。
立即构建

如果你在 UI 完成后才决定权限,通常会得到过多的角色或一堆特殊情况。一个简单计划可以防止不断重建。

1)先从动作而不是屏幕开始

写下每个工作流中人们实际做的事:

  • 查看(read)
  • 创建(create)
  • 编辑(edit)
  • 审批(approve)
  • 导出(export)
  • 删除(delete)

在退款流程中,Approve 并不等于 Edit。这个区分通常决定你需要严格规则还是只需一个角色。

2)定义与职位匹配的角色

选择人们不用开会就能识别的角色名称:Support Agent、Support Lead、Finance Analyst、Finance Manager、Auditor、Admin。避免像 “Support Agent - Can edit VIP notes” 这样的角色,因它们会快速爆炸。

3)列出真正导致例外的属性

只有当 ABAC 真正能带来收益时才添加。典型属性有区域、团队、客户等级、所有权和金额。

如果某个例外发生频率低于每月一次,考虑用人工审批代替永久权限规则。

4)把记录级规则写成一句话的策略

记录级访问是内部工具最易出错的地方。把规则写成你可以拿给非技术经理看的句子:

“Support Agents 可以查看其所在地区的工单。”

“Finance Analysts 可以在发票被审批前编辑他们创建的草稿。”

“Managers 只能为其团队审批 500 美元以上的退款。”

如果你无法用一句话表达规则,说明流程可能需要澄清。

5)在构建前用五个真实人物测试

走一遍真实场景:

  • 一个处理 VIP 客户的支持人员
  • 一个修正发票的财务分析师
  • 一个审批大额退款的经理
  • 一个做维护的管理员
  • 一个必须查看历史但不能更改的审计员

在这里修正混淆,避免它变成权限迷宫。

常见陷阱(以及如何避免)

发布混合 RBAC 与 ABAC 模型
设置 Support、Finance 和 Manager 等通道,然后用属性来处理例外情况。
创建应用

大多数权限失败并不是因为你选了 RBAC 还是 ABAC,而是因为小例外堆积,直到没人能解释谁能做什么以及为什么。

角色爆炸通常从“Support Lead 需要一个额外按钮”开始,然后变成 25 个只差一个权限的角色。保持角色宽泛(与工作匹配),并对重复边缘情况使用少量基于规则的例外。

难以阅读的属性逻辑是 ABAC 版本的同一问题。如果到处都有像 “department == X AND region != Y” 这样的条件,审计会变成猜测。使用命名策略(即使只是共享文档中的一致标签),这样你可以说“RefundApproval policy”而不是解码一个公式。

导出、报表和批量操作是泄露常发生的地方。团队锁定了记录视图,却忘了 Export CSV 或批量更新也会绕过相同检查。把每个非屏幕路径都当作一类首要动作来进行权限检查。

值得注意的陷阱:

  • 为每个例外创建一个新角色
  • 难以阅读或未命名的属性规则
  • 导出、定时报告或批量操作跳过检查
  • 不同工具对同一访问问题给出不同答案
  • 记录级规则只在某个地方生效而不是一致生效

最安全的修复是把角色、属性和记录级规则的单一真理来源放在后端逻辑中并一致强制执行。

上线前的快速检查清单

如果模型难以解释,出现问题时就难以调试,比如有人说“我应该能看到那个客户”或“为什么他们能导出这个列表?”

五项检查能捕获大多数意外:

  • 真正用户能否用一句话描述他们的访问(例如:“我是 Support,region = EU,我可以查看我区域的工单但不能导出”)?如果不能,说明规则可能过于分散。
  • 你是否对“谁能导出?”和“谁能审批?”有明确答案?把导出和审批视为高风险动作。
  • 记录级规则是否在获取数据的所有地方强制执行(API 端点、报表、后台作业),而不仅仅通过隐藏按钮?
  • 敏感操作的默认是安全的吗(默认拒绝)?新角色、属性和页面不应意外继承强权限。
  • 你能否在一分钟内用单一真理来源(角色、属性和记录的所有权/状态)回答“谁能看到这条记录,为什么?”

示例:财务可能能查看所有发票,但只有 Approvers 能审批,且只有 Managers 能导出完整的供应商列表。支持可以查看工单,但只有工单所有者的团队能看到内部备注。

在不破坏现有系统的情况下更改权限

让规则可读且一致
把一句话的策略变成后端逻辑,使用可视化的拖放业务流程保持可读性和一致性。
用 AppMaster 构建

权限会因为琐碎的原因变化:新经理入职、财务拆分为 AP 和 AR、或公司并购添加新团队。为变更做计划,使更新小、可回滚且易审查。

避免把访问绑定到一个大的“超级角色”。以新增角色、属性或窄范围的记录规则来添加访问,然后用真实任务测试。

在不重新设计全部系统的情况下添加访问

当出现新部门(或并购带来团队)时,保持核心角色稳定,并在其周围添加层:

  • 保持基础角色少(Support、Finance、Manager),然后添加小的附加权限(Refunds、Export、Approvals)。
  • 对于组织变更,优先使用属性(team、region、cost center),这样新组不需要新角色。
  • 使用记录级规则来处理所有权和分配(ticket.assignee_idinvoice.cost_center)。
  • 对敏感动作(付款、核销)添加审批步骤。
  • 在大多数场景中把导出视作独立权限。

临时访问不应要求永久角色变更。用于休假替班或事故响应时,采用有时间限制的授权:例如“Finance Approver,48 小时”,并记录到期时间和理由。

审计节奏与可调查的日志

使用简单的复查节奏:高风险权限(月度)、其他权限(季度)、以及在任何重组或并购后复查。

记录足够信息以回答谁对哪个记录做了什么以及为何被允许:

  • 谁查看、编辑、审批或导出
  • 何时发生(以及如果捕捉到位置,也要记录来自何处)
  • 被操作的记录(ID、类型、编辑的前后内容)
  • 为什么被允许(角色、属性、记录规则、临时授权)
  • 谁授权了访问(何时到期)

接下来的步骤:实施一个可维护的模型

从小而无趣的权限模型开始。那才会在六个月的变更中存活。

一个不错的默认是简单 RBAC:少数几个与实际岗位匹配的角色(Support Agent、Support Lead、Finance、Manager、Admin)。用这些角色来控制大门,比如哪些页面存在、可用的动作以及可启动的工作流。

只在你不断遇到相同例外时才添加 ABAC。如果你添加 ABAC 的唯一理由是“以后可能有用”,那就等等。ABAC 在条件重要时(金额限制、区域限制、所有权、状态)表现优异,但需要仔细测试和明确的归责。

先把规则写成一句话。如果一条规则难以一句话说清,它就难以维护。

如果你想快速在真实内部工具中试点这些想法,像 AppMaster(appmaster.io)这样的无代码平台可以帮助你在 UI 决策固化前,建模角色、数据字段(owner/team/status)和后端强制的工作流。

常见问题

我怎么判断应该为内部工具使用 RBAC 还是 ABAC?

默认使用 RBAC,当你的访问决策主要是基于功能且岗位职责稳定时。只有当同一角色需要基于区域、所有权、金额、状态或客户等级做出不同访问决定时,才考虑 ABAC。如果你发现每周都在创建新的“特殊角色”,那说明单纯 RBAC 已经吃不消了。

将 RBAC 和 ABAC 结合使用是否正常?

混合模式通常最易维护。用 RBAC 定义 Support、Finance、Manager、Admin 这样的宽泛通道,然后对重复出现的条件(如区域或审批限额)添加 ABAC 规则,并用记录级过滤确保用户只看到他们应该看到的行。这样既保持入职简单,又不会把例外变成几十个角色。

出现角色爆炸的最清晰信号是什么?

这是角色爆炸的信号:角色开始编码例外而非职责,例如 “Support - EU - Night Shift - Can Refund”。解决办法是把角色简化回与工作职责一致的名称,把可变部分移到属性(region、team、seniority)或工作流步骤(审批)中,这样系统改变时无需成倍增加角色数量。

屏幕级权限和记录级访问有什么区别?

屏幕级权限决定用户是否能打开一个页面或使用某个功能。记录级访问决定在打开页面后他们能读取或修改哪些具体记录,例如仅查看自己负责的工单或仅查看某个成本中心的发票。大多数数据泄露发生在团队锁定了界面但没有在 API 或查询层一致地限定返回数据时。

如何防止导出和批量操作泄露数据?

不要只靠隐藏按钮。在后端的导出端点、报告任务和批量操作中执行相同的权限检查,并把“导出”视为独立的高风险权限。如果某人能导出的数据多于他们在界面上能看到的数据,说明控制不完整。

我应该怎么做让权限更容易审计?

保持简单和一致:少量角色、少量命名策略、以及一个统一的强制执行位置。确保每次读取、编辑、审批、删除和导出都有日志记录(操作者、记录、允许的原因)。如果你不能快速回答“谁可以审批超过 $1,000 的退款?”,说明模型需要收紧。

经理的访问权限通常应该怎么设置?

一个不错的默认是广泛可见但限制编辑。允许经理查看团队和绩效数据,但只允许他们编辑与直接下属或团队关联的记录,使用诸如 manager_idteam_id 的属性。这可以避免把经理赋予“可以编辑所有内容”的权限,从而降低风险和混淆。

如何最安全地处理覆盖或事件响应期间的临时访问?

把它当成有结束时间的访问授权,而不是永久角色变更:例如“Finance Approver,48 小时”,并记录理由和到期时间,支持自动撤销。这样能降低紧急访问悄然变为长期权限的风险。

在构建 UI 之前我应该如何设计权限?

先列出每个工作流里的动作(查看、编辑、审批、导出等),决定哪些角色可以执行这些动作。只在确实能减少角色膨胀时再添加属性,并把记录级规则写成一句话能让非技术经理也能理解。用真实场景测试模型,再去构建大量 UI。

如何在像 AppMaster 这样的无代码平台中实现这些权限想法?

把角色建模为用户字段,保存你关心的属性(team、region、cost center、ownership、status),并把规则放在后端逻辑而不是仅仅界面上。在 AppMaster(appmaster.io)中,你可以定义数据结构、为审批和检查建立业务流程,并确保列表、详情和导出端点都应用相同规则。目标是一个易于修改且一致的单一真理来源。

容易上手
创造一些 惊人的东西

使用免费计划试用 AppMaster。
准备就绪后,您可以选择合适的订阅。

开始吧