本文中,按照“可以复用”,“必须开发”与“有改进潜能”三个维度进行设计评估
下面数据在任何项目都反复使用,这些都是upsert的工作量,不再赘述。需要注意隐私法规。
以下为管理组侧
数据 | 来源 | 功能 |
---|---|---|
用户贴源层 | 第三方IAM Provider系统(SAML/LDAP等) | 证明你是你 |
群组贴源层 | 第三方IAM Provider系统(SAML/LDAP/Directory等) | 证明你在某个集合中 |
SecurityPrincipal | 上述用户与组的贴源数据的并集去重,可以加入额外属性 | 使用侧的缓存 |
注意这里的群组均不涉及到角色(role)和范围(scope),而只是单纯的数组。同时需要做好上下游的数据防篡改,防止关键群组被提权。
关于扩展属性,简单场景可以用数据库的jsonb/字典表/大宽表,复杂场景可以缓存到Redis/ELK/Clickhouse等广义的列存储中提高性能
以下为资源组侧,可以通过菜单、数据源连接,API网关等抽象方案实现,数据管理也可以参考HW的数据湖治理方案。
操作资源 | 来源 | 功能 | 媒介 |
---|---|---|---|
Action | 业务菜单/操作权限 | 对资源进行的读写删操作 | HTTP/GraphQL网关 |
DataAction | SQL等语句,含Where条件的参数 | 查询数据对应的视图 | DB/BI网关 |
Condition | 通过注解/扩展字段等方式录入表达式 | 供ABAC使用的属性 | 手动/第三方录入 |
一定先要做好功能(比如菜单)和数据(比如过滤参数)的防遗漏,比如MECE的枚举方法,然后再考虑导入相关人员角色与Mapping设计。
以下的工作量由于边界/颗粒度难以被公共处理,基本上要自己开发,很考验设计师的抽象能力
网上也有一些SpringBoot的开箱即用的RBAC项目,这种黑盒的后期债务很重,一般来说是不推荐的。
权限关系实现 | 解释对象 | 代表方案 | 优点 | 缺点 |
---|---|---|---|---|
硬编码真值表 | 布尔值 | RBAC数据库 | 数组操作;上手简单 | 难以处理粒度/属性/覆盖问题 |
逻辑等价Logical equivalence | 布尔解释 | 规则引擎/有向图/状态机 | 形式证明;速度快;属性支持强 | 不支持分支/递归;需要逻辑学基础 |
实质等价Material equivalence | 目标语言 | Java/自然语言 | 符合直觉,堆人天,图灵完备 | 代码翻译;上线繁琐;命题歧义 |
上述的区别主要就是分析时的“语境”等级,其中低语境的场景下只需要机器去静态的执行运算器即可(或者通过定时任务定期生成权限关系),而高语境的场景虽然很强,但是需要“动态解释”工作。三种并没有高低贵贱之分。
在传统的数据库判断权限中,底层本质是SQL的交叉运算。那么是否有一种数据结构,能更简化地描述这些细节呢?答案是有向图(以及它的退化Tries,甚至更退化的DFA)。
举例如下,假如需要实现如下的ABAC场景
部门需要开发一套可视化平台,要求如下:
- 如果用户是高级别领导,那么可以看到全部级别数据;如果用户是部门领导,那么只能看到自己部门的数据;如果用户是普通员工,只能看到自己项目的数据
- 所有人的权限级别要高于数据的秘密级别
经验上的流程图如下
如下是用传统过程式的代码实现,符合Java等语言的编程习惯
1 | # 命题: A&((B->G)|(C&F)->G)|(D&E)->G)) |
我们将其转换为逻辑命题
1 | 命题: |
如下是OPA(rego)的实现,它是非时序逻辑。由于不支持if语句,因此产生了重复的语句
1 | # 命题:((A&B)->G)|((A&C&F)->G)|((A&D&E)->G) |
完整Demo与用例在这里 https://play.openpolicyagent.org/p/WFbjph2KyY ,本部分的access_level仅供演示设计
通过上面的例子,我们可以看出声明语言的门槛:你需要手写遍历所有tries的可能性,类似于电路设计中不允许使用寄存器。
无论是Drools/Casbin/OPA,它们本质上都是通过维护rules描述出了一个Trie (Prefix Tree)的数据结构,通过遍历所有的分支,找出第一个返回为true的最短路径(Boolean interceptor),特点如下
但是当前即使在芯片设计中也在推广"低效"的Chisel而不是Verilog,恰恰说明了声明语言的高门槛。
上述的例子尽管从结果上可以看出两种命题是等价的,但是严格的形式证明可以参考《逻辑学导论》中的逻辑等价,或者笛卡尔积相关知识。这种编程风格的门槛非常高。
数据主题指对where条件的限制,即Context based row-level filter,比如用户只能看到自己所在部门的数据,这种场景主要在数据治理与BI分析中非常常见。注意这里的filter指代where条件的过滤项。
大部分权限处理如下:
非业务诉求如下:
这类场景做到最后,就一定会演化到大数据场景,可以参考Huawei的数据湖治理中心服务,或者参考retool的低代码方案。
上述的定制成本均比较高,门槛在于业务专家上。如果追求快而去愿意掏钱的话,个人更建议
如果自己有足够的时间又想用免费的组件,参考如下
如下要求是纯工程问题,可以自行决策是否使用
当你的SaaS项目中存在了很多重要数据时,如何让客户信任你呢?
当然是需要满足SOD(separation of duty,权限职责分离)与自举管理。比如下面是常见的三权分立
角色 | 查看业务数据 | IT日常维护 | 安全管理与审计 |
---|---|---|---|
业务部门(租户) | Y | N | N |
IT维护人员 | N | Y | N |
安全内控部 | N | N | Y* |
上面的需求本质是“权限的权限”,或者“policy ownership”,总体上就是把所有人当贼来防(这个只有大公司/SaaS服务才能这样折腾了),上述有三个问题
真正要做到安全认证的话,这里还是要请安全团队进行渗透测试,软件设计师很难面面俱到。
经过多个技术调研,最终选择基于AntPathMatcher实现类似Azure的IAM的low-code的权限模型,最终全部RBAC合并道ACL中,全部代码只有一个Java文件。只提供一些checkBoolean的无状态接口,因为大部分权限实际开发后发现会和业务的if/where条件耦合。数据权限仍然无法摆脱mybatis或者jinja等模版引擎。
以下主要为基于规则引擎的方案,假如你接触过Drools,那么理解会比较容易
下图是参考Azure云服务术语反推出的ER逻辑图
值得注意的是,云项目中最细的粒度一般是服务实例级别(菜单级),而难以细化到实例内部的数据权限。比如你在租户下申请了K8S集群实例,想分给别人用,很难在管理侧细化到具体的namespace/secret等权限,而需要更细的数据权限方案。
同时也要注意,云项目一般过于复杂,尤其Role是三个多对多,需要规则引擎来实现,中小型快餐项目不推荐照搬使用。假如不涉及到费用、库存和限额,一般也没必要设计资源组的概念。
以下为应用层项目(均基于数据库软隔离的方案,即Sharded multi-tenant databases )
平台 | Gitlab | Sonarqube | Artifactory | SVN |
---|---|---|---|---|
SecurityPrincipal | User/Group | User/Group | User/Group | ACL |
Resources | code | code | artifacts | code |
Top-level-role | nested RBAC | RBAC | ACL | ACL |
Repo-level-role | RBAC | ACL | ACL | ACL |
Path priority & Inheritance | NA | NA | deny>allow,shortest first | longest first |
comment | 总管理员可以看到代码 | Mapping关系复杂度为O(N2) | AntPathMatcher存储RawJSON | 参考 |
上文场景中的Role中绑定的是SecurityPrincipal
,即个人与群组被作为相同的范畴,因此在Sonarqube等工具被看作ACL。
其中Gitlab组织中加入了“角色概念”而不是一个单纯的数组,是失败中的失败,在项目中枚举了50多种,耗费一周后放弃
平台 | retool | Sentry | Metabase-Paid | Redash OSS |
---|---|---|---|---|
SecurityPrincipal | User/Group | User | User/Group | User |
Top-level-role | NA(SaaS) | RBAC | RBAC | ACL |
Project-level-role | RBAC | nested ACL(by copy) | ACL | ACL |
comment | 相对Sonar多了文件夹的概念 | 固定的策略 | 借助了模版引擎精确到ABAC的行级别支持 | 人均管理员 |
常见P层项目
平台 | mgr grp | res grp | mgr member | res member | 评价 |
---|---|---|---|---|---|
OpenLDAP+PAM | root | ACL | User,group | File | 基于chmod实现的Linux HPC |
开源版K8S | RBAC | RBAC | token | resources | 名义上RBAC,事实上都要大量定制 |
AWS_K8S | RBAC | ABAC | user,group, role | resources | AWS的万能方案 |
Harbor | RBAC | FullAccess | User | docker镜像 | 灵活度很差 |
AWS_S3 | RBAC | ABAC | User, Group, role | 精确到文件夹 | AWS的万能方案 |
HashiCorp OSS | ACL | ACL | token | capabilities的集合 | IaaS场景足够了 |
HashiCorp Enterprise | ACL | ACL | token | sentinel | 万能且收费 |
上述可以得出一个结论
权限模型相关术语
微软的RBAC文档写的最好,建议参考这里后再来阅读本文