今天,我们很高兴宣布启动基于属性的访问控制(ABAC)功能。这种新的添加为我们的授权系统带来了全新的粒度,从而更加精确,灵活地访问控制。
在Permify上,我们一直在寻找增强open-source authorization service的方法,使其更加健壮和适应工程团队的各种需求。
,但首先从解释什么是ABAC:基于属性的访问控制(ABAC)就像一个保安人员,决定谁可以根据特定特征或“属性”访问什么。
这些属性可以与用户,资源或环境相关联,其价值可能会影响访问请求的结果。
让我们做一个类比,这是理解复杂思想的最好方法。
考虑一个游乐园,有3种不同的游乐设施。为了获得每次骑行,您需要获得不同的素质。对于;
- 第一次骑行您需要高6英尺。
- 第二次旅程您需要低于200磅。
- 第三次骑行您需要在12-18岁之间。
类似于此ABAC,请检查您在用户,资源或环境上定义的某些素质。
为什么需要ABAC?
很明显但简单的答案是用例 - 有时,使用rebac和rbac并不是最适合这份工作的。这就像在炎热的沙漠道路上使用冬季轮胎,或在暴风雪中使用夏季轮胎 - 它们只是适合这种情况的正确工具。
- 在地理上受到限制:将阿巴克(Abac)视为俱乐部的弹跳者,他只允许某些城镇的人们。例如,电影流服务可能只会在某些国家/地区展示某些电影,因为有关谁可以观看什么和地点。 。
- 基于时间的: ABAC也可以像您何时可以使用计算机的父母设置规则一样行动。例如,系统只能在办公时间内完成某些事情。
- 遵守隐私条例: Abac可以帮助遵循有关隐私的规则。例如,医院系统可能需要限制谁可以根据患者的许可查看患者的数据,为什么要看它以及该人是谁。
- 限制范围: ABAC可以帮助您创建定义数字限制或范围的规则。例如,银行系统可能会限制接线或提取钱。
- 设备信息: ABAC可以根据设备的属性(例如设备类型,操作系统版本)控制访问权限,或者设备是否具有最新的安全补丁。
您可以看到Abac具有更多的上下文方法。您可以在应用程序中定义有关主题和对象的上下文的访问权限。
简而言之允许授权?
在深入研究ABAC功能之前,请总结现有的授权在Permanify中的工作原理。
Permandify具有定义您的授权模型的特定域语言。它可以通过在应用程序中的对象和主题之间建立关系来帮助您创建层次结构。
例如,在Google驱动器中,您拥有文档编辑器,该允许用户编辑给定文档。假设用户 james 想要编辑名为 博客文章 以编辑
在这里,您如何在Permanify中创建相同的系统;
Entity user {}
Entity docs {
relation editor @user
relation viewer @user
permission edit = editor
permission view = editor or viewer
}
介绍新的密钥元素
为了支持ABAC在Permerify中,我们在DSL中添加了两个主要组件:属性和规则。
属性
属性用于定义特定数据类型中实体的属性。例如,属性可能是与组织相关联的IP范围,该IP范围定义为字符串数组:
attribute ip_range string[]
您可以使用不同类型的属性;
布尔
对于代表二进制选择或状态的属性,例如是/否问题, boolean 数据类型是一个绝佳的选择。
entity post {
attribute is_public boolean
permission view = is_public
}
如果您不创建相关属性数据,请将帐户boolean作为 false
字符串
字符串可以用作属性数据类型,在各种情况下,需要基于文本的信息来做出访问控制决策。这里有几个例子:
- 位置:如果您需要基于地理位置控制访问权限,则可能具有存储为字符串的位置属性(例如,“美国”,“ eu”,“ Asia”)。
- 设备类型:如果访问控制决策需要考虑使用的设备类型,则可以将设备类型属性(例如“移动”,“桌面”,“平板电脑”)作为字符串存储。
- 时区:如果需要根据时区控制访问,则可以将时区属性(例如,“ EST”,“ PST”,“ GMT”)存储为字符串。
- 一周中的一天:在某些资源访问时,在一周中的一天确定的情况下,字符串数据类型可用于代表这些天(例如,“星期一”,“星期二”,“星期二”等等)作为属性!
entity user {}
entity organization {
relation admin @user
attribute location string[]
permission view = check_location(request.current_location, location) or admin
}
rule check_location(current_location string, location string[]) {
current_location in location
}
如果您不创建相关属性数据,请将帐户字符串作为 空
整数
整数可以用作属性数据类型,在几种情况下,需要数值信息来做出访问控制决策。这里有几个例子:
- 年龄:如果对某些资源的访问是受年龄限制的访问,则可以使用作为整数存储的年龄属性来控制访问。
- 安全间隙级别:在用户具有不同安全间隙级别的系统中,可以将这些级别存储为整数属性(例如1,2,3,其中3是最高的间隙)。
- 资源大小或长度:如果根据其大小或长度控制对资源的访问(例如文档的长度或文件的大小),则可以将其存储为整数属性。
- 版本号:如果访问控制决策需要考虑资源的版本编号(例如软件版本或文档修订版),则可以将其存储为整数属性。
entity user {
attribute age integer
permission view = check_age(age)
}
entity content {
relation user @user
attribute budget double
permission view = user.view
}
rule check_age(age integer) {
age >= 18
}
如果您不创建相关属性数据,请将帐户整数置于 0
double
双重可以用作属性数据类型,在几种情况下,需要精确的数值信息来做出访问控制决策。这里有几个例子:
- 使用限制:如果用户具有使用限制(例如他们可以使用的存储量或可以下载的数据量),并且需要用小数点精度表示此限制,则可以是存储为双重属性。
- 交易金额:在金融系统中,如果访问控制决策需要考虑交易金额,并且该金额需要用小数精度表示(例如$ 100.50),则这些金额可以存储为double属性。
- 用户评分:如果访问控制决策需要考虑用户的评分(例如用小数点(例如4.7)的5个评分),则可以将这些评级存储为双属性。
- 地理位置:如果访问控制决策需要考虑精确的地理坐标(例如纬度和经度,通常用小数点表示),则可以将这些坐标存储为双属性。
entity user {}
entity account {
relation owner @user
attribute balance double
permission withdraw = check_balance(request.amount, balance) and owner
}
rule check_balance(amount double, balance double) {
(balance >= amount) and (amount <= 5000)
}
如果您不创建相关属性数据,请将帐户置于 0.0
diles double规则
规则是使您可以为模型编写特定条件的结构。他们接受参数并基于条件。例如,可以使用规则来检查给定的IP地址是否属于指定的IP范围:
rule check_ip_range(ip string, ip_range string[]) {
ip in ip_range
}
建模ABAC
让我们看一下如何使用一个实践示例在Pressify中实现ABAC。假设我们有一个与用户实体关系和IP范围属性关系的组织实体。我们可以根据CHECK_IP_RANGE规则或管理员关系来定义用于查看组织的权限规则:
entity organization {
relation admin @user
attribute ip_range string[]
permission view = check_ip_range(request.ip_address, ip_range) or admin
}
请求中的“上下文”是指请求的上下文。任何类型的数据都可以从请求中添加,并且可以在模型中调用。例如:
"context": {
"ip_address": "187.182.51.206",
"day_of_week": "monday"
}
现实生活中的例子
让我们发现一些现实生活中的例子加强了我们学到的知识。
汞批准
对于那些不知道的人,水星是专门为初创公司设计的银行,提供支票和储蓄帐户,并提供借记卡和信用卡功能。鉴于金融交易的微妙性质,水星具有内置的访问控制功能以确保安全性。
,但是今天我们将重点关注批准。 Mercury允许用户为任何操作设置数量以供多个用户批准。
例如,管理员可以决定成员以上$ 1000的提款需要两个指定批准者的批准。这意味着,如果成员想撤回超过1000美元,则需要两个管理员的绿灯。如果管理员试图撤回,他们需要批准另一个管理员。
- 管理员提取$ 1000需要批准者
- 会员撤回$ 1000的需要2个批准者。
所以让我们从建筑基础开始。我们需要用户,组织,帐户储蓄和存款作为汞中的实体
entity user {}
entity organization {
}
entity teams {
}
entity accounts {
}
然后将关系插入这些实体。
entity user {}
entity organization {
relation admin @user
relation member @user
}
entity accounts {
relation checkings @accounts
relation savings @accounts
relation org @organization
}
下一步是在我们的用例中定义动作。
entity user {}
entity organization {
relation admin @user
relation member @user
}
entity account {
relation checkings @account
relation savings @account
relation org @organization
action withdraw =
}
现在,我们需要定义我们的属性,这将帮助我们通过 提取限制 和 admin批准 帐户的>
每个组织都有一个集合 撤回限制 。此外,对于组织的成员和管理员,当他们试图撤回超过此限制的金额时,也有特定的 批准限制 。
entity user {}
entity organization {
relation admin @user
relation member @user
}
entity account {
relation checkings @account
relation savings @account
relation org @organization
attirbute approval integer
attribute balance double
action withdraw =
}
让我们创建定义基于属性的访问权限的规则。
- 帐户的余额必须超过撤回金额
- 如果提取金额小于提取限制,我们不需要批准
- else;如果我们担任会员,我们需要批准两个管理员,如果我们是另一个管理员,则需要批准单个管理员。
entity user {}
entity organization {
relation admin @user
relation member @user
}
entity account {
relation checkings @account
relation savings @account
relation org @organization
attirbute approval integer
attribute balance double
action withdraw = check_balance(request.amount, balance) and (check_limit(request.amount, request.withdraw_limit) or (org.admin and check_approval(approval, request.approval_limit)) or (org.member and check_approval(approval, request.approval_limit)))
}
rule check_balance (amount double, balance double) {
amount =< balance
}
rule check_limit (amount double, withdraw_limit double){
amount =< withdraw_limit
}
rule check_approval (approval integer, approval_limit integer) {
approval >= approval_limit
}
最终,您可以看到,我们使用 规则 来定义撤回访问权限,该权利基本上转化为;
- 检查余额是否超过撤回金额。如果不允许行动。
- 支票提取限制;如果少于限制允许行动
- else;
- 检查用户是否是管理员,并拥有超过管理员的批准限制。
- 检查用户是否是会员,并且拥有超过成员批准限额的批准。
Instagram私有个人资料
让我们从我们的第一个示例开始,以理解primal abac。如您所知,几乎每个社交媒体应用程序都有私人/公共个人资料设置。例如,在Instagram上,您可以将您的个人资料变成一个私人个人资料,只有您的关注者才能查看或评论您的帖子。
,甚至我们可以走得更远,并设置授权规则,该规则只允许您跟随的人在某个帖子上发表评论,但您的追随者。
让我们从构建块开始;我们有用户,帐户和发布。
entity user {}
entity account {
}
entity post {
}
现在我们建立了核心,让我们填写我们在Instagram应用程序上的关系。
entity user {}
entity account {
//users have accounts
relation owner @user
//accounts can follow other users/accounts.
relation following @user
//other users/accounts can follow account.
relation follower @user
}
entity post {
//posts are linked with accounts.
relation owner @account
}
让我们建立我们的属性。我们想要两个主要功能;
- 定义我们的帐户是私人的还是公共的。
- 只允许您遵循的人对某些帖子发表评论。
entity user {}
entity account {
//users have accounts
relation owner @user
//accounts can follow other users/accounts.
relation following @user
//other users/accounts can follow account.
relation follower @user
//accounts can be private or public.
attribute private boolean
}
entity post {
//posts are linked with accounts.
relation owner @account
//comments are limited to people followed by the parent account.
attribute public_comment boolean
}
下一步是构建我们的权限,或者换句话说可以采取哪些行动。在Permerify中,这通常由对象与受试者之间的关系定义。
例如, 如果用户:ryu是POST:1的所有者,Ryu可以删除帖子:1
正如我们建立的,随着ABAC更新,您可以使用属性或关系等规则。
entity user {}
entity account {
//users have accounts
relation owner @user
//accounts can follow other users/accounts.
relation following @user
//other users/accounts can follow account.
relation follower @user
//accounts can be private or public.
attribute private boolean
//Users can view an account if they're followers, owners, or if the account is not private.
action view = (owner or follower) not private
}
entity post {
//posts are linked with accounts.
relation owner @account
//comments are limited to people followed by the parent account.
attribute restricted boolean
//users can view the posts, if they have access to view the linked accounts.
action view = owner.view
//users can comment on unrestricted posts or posts by owners who follow them.
action comment = owner.following not restricted
}
迪士尼+位置
迪斯尼的流媒体服务迪斯尼+具有许多访问控制功能,但我们将重点遵守区域和年龄过滤内容。迪士尼+提供了各种各样的内容,但有些可能取决于您的位置和年龄。
最直接的访问控制功能是基于年龄的。
例如,如果内容对暴力行为进行+18的评分,并且您的个人资料年龄为16岁,则无法访问它。即使同一帐户上的另一个配置文件为+18。
我们可以通过添加区域来进一步完善这一点,从而带来不同的访问控制方案。我们可以创建一个规则,其中所选区域必须与内容的允许区域保持一致,从而为内容过滤增加了复杂性。
我们还可以建立一个需要将IP地址范围与所选区域匹配的访问控制层,以确保真正的区域访问。
让我们从建立基本块开始;帐户,个人资料,内容和手表列表。
entity user {}
entity account {
}
entity profile {
}
entity watch-list {
}
entity content {
}
简单地解释;用户有帐户,帐户将具有多个或单个配置文件,在每个配置文件中,您可以创建一个手表列表并在手表列表中添加不同的内容。
为了做这些,让人建立关系;
entity user {}
entity account {
//users own an account.
relation owner @user
}
entity profile {
//Accounts can own a multiple profiles.
relation owner @account
}
entity watch_list {
//each profile can own a multiple watch-list.
relation owner @profile
}
entity content {
//contents can be a part of watch_lists
relation watch-list @watch_list
}
下一步是定义我们的规则和属性,以创建我们一直在描述的额外访问控制层。
entity user {}
entity account {
//users own an account.
relation owner @user
action create_profile = owner
}
entity profile {
//Accounts can own a multiple profiles.
relation owner @account
action edit = owner
action delete = owner
action create_watchlist = owner
}
entity watchlist {
//each profile can own a multiple watch-list.
relation owner @profile
action edit = owner
action delete = owner
action remove_content = owner
}
entity content {
//contents can be a part of watch_lists
relation watchlist @watchlist
relation user @profile
attribute age_rating integer
attribute allowed_region string[]
action view = check_age(request.age, age_rating) and check_region(request.region, allowed_region) and check_ip (request.ip, user.region_ip)
action add_watchlist = user
}
rule check_age (age integer, age_rating integer) {
age >= age_rating
}
rule check_region (region string, allowed_region string) {
region in allowed_region
}
rule chekck_ip (ip string, region_ip string) {
ip in region_ip
}
entity user {}
entity account {
//users own an account.
relation owner @user
attribute region string[]
attribute region_ip string[]
action create_profile = owner
}
entity profile {
//Accounts can own a multiple profiles.
relation owner @account
attribute age integer
attribute region string[]
attribute region_ip string[]
action edit = owner
action delete = owner
action create_watchlist = owner
}
entity watchlist {
//each profile can own a multiple watch-list.
relation owner @profile
action edit = owner
action delete = owner
action remove_content = owner
}
entity content {
//contents can be a part of watch_lists
relation watchlist @watchlist
relation user @profile
attribute age_rating integer
attribute allowed_region string[]
action view = check_age(user.age, ager_rating) and check_region(user.region, allowed_region) and check_ip (request.ip, user.region_ip)
action add_watchlist = user
}
rule check_age (age integer, age_rating integer) {
age >= age_rating
}
rule check_region (region string, allowed_region string) {
region in allowed_region
}
rule chekck_ip (ip string, region_ip string) {
ip in region_ip
}
阿巴克的力量
引入ABAC在Permerify中为平台工程团队开辟了一个可能性。它允许对访问权限进行更精细的控制,从而使团队能够创建更复杂和灵活的授权系统。使用ABAC,您可以根据与用户或资源关联的任何属性来定义访问控制规则,从而提供高水平的自定义和精度。
我们对新的ABAC功能的潜力感到兴奋,并期待看到如何利用它来创建更健壮和灵活的访问控制系统。与往常一样,我们渴望听到您的想法和反馈。快乐的授权!