权限管理策略对决:RBAC vs. ABAC vs. ReBAC


与我们一起寻找史诗般的大逃杀中的最佳授权策略模型:RBAC vs. ABAC vs. ReBAC

区分授权和身份验证非常重要 :区分两者就像理解 401 和 403 之间的区别一样简单:

  • 401 - 当您尝试进入俱乐部时,您需要向保镖出示您的身份证件,但您把它留在家里了。
  • 403 - 当您在俱乐部内但未邀请您进入 VIP 区域时

在应用程序开发中,身份验证处理 谁可以登录您的应用程序,而授权处理 他们进入应用程序后可以执行的操作。

授权很快就会变得非常复杂。它可以从简单的事情开始,例如“检查该用户是否是管理员,然后根据该情况授予他们访问权限”,但随着应用程序的发展,授权要求也会随之变化。很快,您可能最终需要根据多种角色类型、属性(如地理位置或付款状态)、团队关联、层次结构等授予访问权限。

这就是 授权模型发挥作用的地方。在这篇博客中,我们为您带来一些最常见的授权模型之间的对峙: 基于角色的访问控制(RBAC)、 基于属性的访问控制(ABAC)和 基于关系的访问控制(ReBAC)。我们将涵盖所有这三个方面,重点关注每个方面的用例、优点和缺点。 

1、基于角色的访问控制 (RBAC):
经典、久经考验的冠军。 基于角色的访问控制 (RBAC)使用 分配给用户的预定义角色来确定他们的访问权限。简单而优雅,RBAC 多年来一直是许多应用程序开发人员的首选。

在 RBAC 中,为用户分配 角色,例如“管理员”或“编辑者”,每个角色与特定权限相关联。 
简单英语的 RBAC 策略如下所示: 
员工 可以 查看 和 编辑文档,而 管理员 可以 查看、 编辑、 创建和 删除 文档。
优势: 

  • 简单性:RBAC 提供了一种对开发人员和最终用户来说简单且熟悉的解决方案。
  • 易于管理:RBAC 设置的预定义角色可以与个人的工作职能或职责等方面相关联。这允许管理员在较高级别管理权限,而不是针对单个用户。
  • 可扩展性:RBAC 使开发人员能够随着应用程序的增长而轻松地进行扩展。如果实施正确,添加或删除角色和权限可能是一项简单的任务。
  • 高性能:由于策略执行简单,与其他策略模型相比,RBAC 通常具有更高的性能能力。 

弱点: 
  • 容量有限:RBAC 在更复杂的应用程序中很容易出现“角色爆炸”——在这种情况下,为了粒度的目的,创建了许多角色,这使得管理/审计变得极其困难)。
  • 灵活性有限:由于用户访问仅由角色而不是特定属性定义,因此当出现新的、更细粒度的访问控制需求时,RBAC 系统很快就会变得不足。

下面是用Rego (开放策略代理 (OPA)的策略语言) 编写的 RBAC 策略的简单示例 。 
开放策略代理 (OPA) 是一种开源策略引擎,用于控制对系统和资源的访问。它允许将策略逻辑与应用程序代码分离,从而实现轻松的策略管理和更新,而无需更改或部署代码。

default allow = false
allow {
    # Lookup the list of roles for the user
    roles := user_roles[input.user]
    # For each role in that list
    r := roles[_]
    # Lookup the permissions list for role r
    permissions := role_permissions[r]
    # For each permission
    p := permissions[_]
    # Check if the permission granted to r matches the user's request
    p == {"action": input.action, "object": input.object}
}

RBAC 以及其他策略模型可以通过不同的策略引擎和语言来实现 

这里还有一些详细的示例,介绍如何 使用 OPA 实现 RBAC以及如何使用 Cedar (AWS 的开源策略引擎)实现 RBAC。

2、基于属性的访问控制 (ABAC): 
我们最强大的挑战者是 基于属性的访问控制 (ABAC),它使用 属性 (用户、资源、操作和环境条件的各个方面)来确定访问权限。用途无限,没有比这更精细的了。

ABAC 在基本 RBAC 角色的基础上进行了扩展,将属性添加到组合中,从而允许创建更细粒度的授权策略。 

简单英语的 ABAC 政策如下所示: 
欧盟境内的 员工 可以 编辑受 GDPR 保护的文档 。

在这个例子中:

  • 员工是一个 角色
  • 员工在欧盟的位置是一个 用户属性
  • 编辑就是 行动
  • 文档就是 资源
  • GDPR 保护的是 资源属性

ABAC 对属性的使用允许创建非常细粒度的授权策略。常见属性包括(但不限于):时间、位置、计费状态等等 - 所有这些都取决于您的应用程序的特定需求。 

优势: 

  • 细粒度: ABAC 能够通过使用属性来创建极其细粒度的访问控制策略。
  • 高度动态:应用程序通常依赖于必须以实时方式管理的功能。如果使用正确的工具实施,ABAC 可以根据用户/资源属性的实时变化提供动态访问控制。

弱点:
  • 复杂性: ABAC 的实施、管理和维护可能是一个巨大的挑战。设计不仅非常复杂且耗时,而且是一项持续的努力。 
  • 资源密集型:由于 ABAC 可能需要考虑大量属性,因此它可能非常资源密集型,需要更多的处理能力和时间。

以下是用Rego编写的 ABAC 策略的示例 : 

package abac

# User attributes
user_attributes := {
    "User1": {"location": "EU", "title": "employee"},
   
"User2": {"location": "US", "title": "employee"},
   
"User3": {"location": "EU", "title": "manager"}
}
# Document attributes
document_attributes := {
   
"Doc1": {"classification": "GDPR Protected"},
   
"Doc2": {"classification": "Non-sensitive"}
}
# Default deny
default allow = false
# EU employees can perform any action on GDPR Protected Document
allow {
    # Lookup the user's attributes
    user := user_attributes[input.user]
    # Check that the user is an employee
    user.title ==
"employee"
    # Check that the employee is based in the EU
    user.location ==
"EU"
    # Check that the document is GDPR Protected
    document_attributes[input.document].classification ==
"GDPR Protected"
}
# Allow any employee to access non-GDPR-protected documents
allow {
    # Lookup the user's attributes
    user := user_attributes[input.user]
    # Check that the user is an employee
    user.title ==
"employee"
    # Lookup the document's attributes
    document := document_attributes[input.document]
    # Check that the document is not GDPR Protected
    document.classification =
"Non-sensitive"
}

要了解有关使用 OPA 的 Rego 实施 ABAC 的更多信息, 请查看本指南

3、基于关系的访问控制 (ReBAC): 
基于关系的访问控制(ReBAC)依赖于实体之间的关系来做出访问决策,使其最适合处理层次结构。

ReBAC允许我们根据现有的应用程序级关系导出授权策略。简而言之,它允许我们创建这样的策略:
作为 文件夹 所有者 的 用户 还将获得 该 文件夹中每个文件的 所有者 访问 权限 。 
基于关系而不是角色或属性创建策略使我们不必在每个实例的基础上创建授权策略。 
优势: 

  • 处理复杂的层次结构:ReBAC 旨在表示层次结构和嵌套关系,使其成为此任务的最合适选择。
  • 启用反向索引:ReBAC 的图结构允许反向查询(不仅 x 可以访问 y,还可以知道谁可以访问 y)。
  • 使用 ReBAC 允许我们 集体定义权限,而不是使用团队和组为每个资源单独定义权限。 

弱点: 
  • 复杂性:自行实施、管理和维护 ReBAC 可能非常复杂且耗时。
  • 资源密集型: ReBAC 对众多属性的考虑可能需要大量的处理能力和时间。
  • 难以审计: ReBAC 策略的复杂性和递归性可能使审计变得具有挑战性。

以下是用Rego编写的 ReBAC 策略的示例 : 
# return a full graph mapping of each subject to the object it has reference to
full_graph[subject] := ref_object {
    some subject, object_instance in object.union_n([files, teams,organizations])
    # get the parent_id the subject is referring
    ref_object := [object.get(object_instance, “parent_id”, null)]
}
# … see full Rego code at https://play.openpolicyagent.org/p/4qkNc0GtPP
# rule to return a list of allowed assignments
allowing_assignments[assignment] {
    # iterate the user assignments
    some assignment in input_user.assignments
    # check that the required action from the input is allowed by the current role
    input.action in data.roles[assignment.role].grants
    # check that the required resource from the input is reachable in the graph
    # by the current team
    assignment.resource in graph.reachable(full_graph, {input.resource})
}

包含一些示例数据的完整 rego 代码可在 OPA Playground中找到
要了解有关使用 OPA 的 Rego 实施 ReBAC 的更多信息, 请查看本指南

第一轮:RBAC 与 ABAC
在我们的第一场比赛中,我们将两种授权模型相互竞争:  RBAC 和 ABAC。

想一想:俱乐部--保镖(身份验证)让你进去。现在怎么办?你能跳舞吗?你能给别人倒酒吗?你可以进入贵宾区吗?

RBAC 可以非常直接地解决这个问题:"有合适的角色吗?请便"。这种直接方法简单、易于理解和管理,通常足以满足简单应用的需要。

然而,RBAC 方法有时会过于死板。它严格按照角色行事,而不考虑任何其他因素。

ABAC 不只是检查角色,还有访客名单、时间戳,甚至还可能检查天气!这意味着它允许我们做出更细致的决定。

这种精细也伴随着复杂性。ABAC 考虑的细节越多,可能需要的时间和资源就越多。

现在,问题来了:这两者并不总是对立的--RBAC 和 ABAC 可以一起使用,RBAC 协议执行广泛的访问,而 ABAC 则管理更复杂的访问。

许多组织一开始使用的是 RBAC 的明确规则,然后在需要额外属性时逐渐将其发展为 ABAC。

当时间、地点、计费状态和当前行为等动态数据点生效时,ABAC 就变得非常必要。


第二回合:RBAC 对 ReBAC
随着第二轮比赛钟声的敲响,我们又把 RBAC 送上了擂台,这次的对手是 ReBAC。

回到上一节的比喻,想想俱乐部里的贵宾休息室,那里有舞池和贵宾吧台。如果使用 RBAC,我们就必须给 VIP 客人发放 3 个徽章--一个允许他们进入休息室,一个允许他们在舞池中跳舞,还有一个允许他们在吧台点饮料。

另一方面,ReBAC 允许我们根据现有的应用级关系定义访问策略。ReBAC 可以识别不同区域之间的关系,以更高效的方式授予访问权限,而不是为每个区域设置多个徽章。

ReBAC 政策可能规定:“VIP 休息室的客人还可以在舞池跳舞并在 VIP 酒吧点饮料 - 如果舞池和 VIP 酒吧位于 VIP 休息室内”。 

从更实际的角度来看,ReBAC 的方法在分层或分组设置中表现出色。尽管 RBAC 可能需要为每个相关领域定义多个角色,但 ReBAC 通过识别和应用固有关系和层次结构来应对这些复杂性。 

使用 ReBAC 允许我们建立一个类似于 Google Drive 的系统,如果您拥有某个文件夹的编辑访问权限,那么您就拥有该文件夹中每个文件的编辑访问权限。 

(banq注:ABAC、ReBAC与业务上下文 更多相关)

第 3 轮:ABAC 与 ReBAC
让我们继续我们的俱乐部比喻--设想一个用户,我们叫他杰伦,在我们的俱乐部里有一个储物柜。这个储物柜里有不同的物品,杰伦希望确保他能使用自己拥有的所有物品。

有了 ABAC,就好比在杰伦储物柜中的每件物品上都添加了一个特定的标签,上面写着 "杰伦的财产"。每次杰伦想要取东西时,俱乐部都会检查该标签是否存在。给每件物品贴上 "所有者=周杰伦 "的标签非常精确,但效率不高。

另一方面,ReBAC 允许我们简单地定义一个策略,比如 "客人可以取用自己储物柜里的所有物品--如果物品在储物柜里的话"。  无需在每件物品上都贴上标签。

通过利用物品与储物柜之间的固有关系,ReBAC 可以构建更简单、更高效的访问策略。

反过来,让我们想象一个精致的鸡尾酒吧,每种饮品都需要特定的配料组合和正确的调酒技巧。这正是 ABAC 的优势所在!ABAC 可以根据多种属性确定哪位调酒师可以调制哪种鸡尾酒,以及客人中谁可以点这种鸡尾酒。这样,我们就能制定出类似 "客人只有在午夜后坐在吧台前,才能点特定酒水 "的政策。ABAC 的专长在于通过拼凑多个属性来制定这些复杂而详细的规则。

因此,ReBAC 可以毫不费力地浏览基于关系授予访问权限的层次结构,而 ABAC 则允许我们针对细微场景制定和执行多属性规则。
(banq注:ReBAC针对上下文 之间关系映射;ABAC则针对上下文 内部权限规则)

在许多情况下,两种策略模型也可以结合使用,基于 ReBAC 的策略可以执行分层,而 ABAC 则可以管理更精细的访问。