3、属性设计:ABAC 的四大基石
属性设计,说白了就是给 ABAC 策略准备“原材料”。没有好的属性,策略写得再漂亮也是空中楼阁。我见过太多项目,策略引擎搭好了,结果发现属性定义得乱七八糟,最后权限控制一塌糊涂。
今天咱们就把这四类属性掰开揉碎了讲清楚。你想想看,一个访问控制决策,无非就是回答四个问题:谁在什么环境下,对什么资源执行什么操作。对应的就是用户属性、环境属性、资源属性和操作属性。
核心原则:属性设计要遵循“够用就好”的原则。别一开始就想把所有字段都塞进去,那会让策略变得臃肿不堪。我建议先覆盖 80% 的场景,剩下的边用边补。
3.1 用户属性:Who are you?
用户属性是最直观的一类。它描述的是“谁”在发起请求。但这里有个坑——很多人把用户属性和用户身份混为一谈。身份只是用户属性的一个维度。
我个人习惯把用户属性分成三层:
- 基础身份层:用户ID、用户名、邮箱、工号。这些是唯一标识,用来定位到具体的人。
- 组织关系层:角色、部门、职级、汇报线。这一层决定了用户在组织里的位置。
- 安全等级层:安全等级、涉密等级、信任评分。这一层决定了用户能接触什么敏感度的信息。
举个例子,我在一个金融项目里遇到过这样的场景:同样是“交易员”角色,初级交易员只能查看自己名下的交易记录,高级交易员可以查看团队记录,而风控总监可以查看全量数据。光靠角色是不够的,还得加上职级和部门属性。
| 属性类别 | 典型属性 | 取值示例 |
|---|---|---|
| 基础身份 | user_id, username, email | u10086, zhangsan, zhang@corp.com |
| 组织关系 | role, department, level | engineer, R&D, P7 |
| 安全等级 | clearance, trust_score | L3, 85 |
我的经验:用户属性尽量从统一身份认证系统(IDP)同步,不要每个应用自己维护一份。否则你会发现,同一个人的角色在三个系统里是三个值,那策略就没法写了。
3.2 资源属性:What is it?
资源属性描述的是被访问的对象。可以是文件、数据库记录、API 接口、微服务,甚至是一台物理服务器。
我建议资源属性至少包含三个维度:
- 类型:文件、数据库表、API、页面、设备。不同类型的资源,管控粒度完全不同。
- 分类:财务数据、客户信息、源代码、运维日志。分类决定了这个资源属于哪个业务域。
- 敏感度:公开、内部、机密、绝密。敏感度直接和安全等级挂钩。
嗯,这里要注意。资源属性往往不是静态的。比如一份文档,创建时是“内部”,过了一年可能变成“公开”。我见过一个项目,资源敏感度写死在代码里,结果每次变更都要发版,折腾得运维团队苦不堪言。
避坑指南:资源属性一定要支持运行时动态计算。比如“文档的敏感度 = max(创建者安全等级, 文档内容分类默认值)”。别把属性值写死,否则策略会变得极其僵硬。
3.3 环境属性:Where and When?
环境属性是 ABAC 区别于 RBAC 的一大亮点。它让权限控制从“静态”走向“动态”。
常见的环境属性包括:
- 时间:当前时间、工作日/节假日、业务时段(交易时间、非交易时间)。
- 地点:IP 地址段、物理位置(GPS)、网络区域(内网/外网/VPN)。
- 设备状态:设备是否合规、是否越狱、是否安装安全软件、补丁版本。
我曾经帮一家银行做零信任项目,他们的要求是:只有在内网、工作时间、且设备合规的情况下,才能访问核心交易系统。这三个条件缺一不可。你看,这就是环境属性的威力。
| 环境维度 | 典型属性 | 策略示例 |
|---|---|---|
| 时间 | current_time, is_business_hour | 仅 09:00-18:00 允许写操作 |
| 地点 | ip_range, network_zone | 仅内网 IP 段允许管理操作 |
| 设备 | is_compliant, os_version | 仅合规设备允许访问敏感数据 |
小技巧:环境属性最好由策略引擎自动采集,不要依赖客户端上报。客户端上报的数据容易被篡改。比如设备是否越狱,应该由服务端的安全代理来检测,而不是让 App 自己说“我没越狱”。
3.4 操作属性:What action?
操作属性是最容易被忽视的一类。很多人觉得操作不就是“读、写、执行”嘛,有什么好设计的?其实不然。
操作属性的设计要跟资源类型匹配。比如:
- 对文件:read, write, delete, rename, share
- 对 API:GET, POST, PUT, DELETE, PATCH
- 对数据库:select, insert, update, delete, truncate
- 对设备:start, stop, restart, configure
我建议把操作属性设计成枚举值,并且支持层级关系。比如“write”可以包含“create”和“update”,“admin”可以包含所有操作。这样策略写起来更灵活。
关键点:操作属性不要跟资源类型耦合太紧。同一个操作名在不同资源类型下含义可能不同。比如“delete”对文件是删除文件,对数据库是删除记录,对设备是关机。策略引擎要能区分上下文。
3.5 属性设计的最佳实践
说了这么多,最后总结几条我踩过坑之后得出的经验:
- 属性命名要规范。用 snake_case 或 camelCase 都行,但团队内部必须统一。我见过一个项目,有的属性叫“userRole”,有的叫“user_role”,策略里还得写两套,烦得很。
- 属性值要标准化。比如“部门”这个属性,是用“R&D”还是“研发部”?统一用编码,别混着来。
- 属性来源要清晰。每个属性只能有一个权威数据源。用户属性来自 IDP,资源属性来自 CMDB,环境属性来自安全代理。别搞出多个数据源互相覆盖的情况。
- 属性要有版本和有效期。用户的角色会变,资源的敏感度会变,环境的状态会变。属性值要有时间戳,策略引擎才能判断“当时”的属性是什么。
说实话,属性设计做得好,ABAC 就成功了一半。很多团队一上来就写策略,结果发现属性不够用或者属性冲突,最后推倒重来。我建议你花 40% 的时间在属性设计上,剩下的 60% 再写策略和测试。
最后提醒一句:别把属性设计搞成“大而全”的完美主义。先跑起来,再迭代。你永远不可能一开始就设计出完美的属性模型,但你可以设计出一个能扩展的属性框架。