2. 权限管理基础概念:主体、客体、操作、权限规则与策略
权限管理这东西,听起来玄乎,说白了就四个词:谁(主体)、对什么(客体)、做什么(操作)、怎么管(规则与策略)。我们在SDK里做隐私共享,其实就是在回答这四个问题。我记得刚入行时,总觉得只有操作系统内核才需要权限管理,后来被甲方追着改了好几版才明白——SDK里的权限比系统级还麻烦,因为你不光要管App,还得管App里的模块。
2.1 主体(Subject)
主体就是“谁”在发起请求。在隐私共享SDK里,主体可以是:
- 第三方App进程(最常见的主洗)
- App内的子模块或插件(比如一个广告组件)
- 远程服务调用者(跨进程或跨设备)
- 用户代理(经用户授权后的自动化程序)
2.2 客体(Object)
客体就是主体要访问的“东西”。在隐私共享场景里,客体一般是:
- 用户数据项:通讯录、位置、相册、设备标识符
- SDK内部资源:加密密钥、缓存池、日志流
- 特定功能接口:比如“上报数据API”、“删除记录API”
这里有个坑:客体粒度太粗的话,后期根本没法单独管控。我曾经接了一个SDK,把“所有用户数据”当成了一个客体,结果想单独禁止某个App读取位置都不行。所以建议一开始就把客体拆细,比如“com.example.location.gps”和“com.example.contacts.phones”。
2.3 操作(Operation)
操作就是主体对客体“做什么”。常用的操作集:
- 读取(read):获取数据内容
- 写入(write):修改或新增数据
- 删除(delete):移除数据项
- 执行(execute):调用一个功能接口
- 共享(share):把数据传给第三方(比较特殊,我后面会讲)
避坑指南:我曾经把“读取”和“写入”权限用同一个位掩码来标记,结果某个App强行把写操作伪装成读操作。后来我强制规定:每个操作必须有独立的标识符,并且在SDK内部使用白名单校验。
2.4 权限规则与策略
有了主体、客体、操作,接下来就是“怎么判定”。权限规则是一条条具体的判断条件,而策略是规则的集合,包含优先级、合并方式、默认行为。
2.4.1 规则(Rule)
规则通常写成三元组:(主体, 客体, 操作) → 允许/拒绝。举个例子:
// 规则表示:包名为 com.example.reader 的App,允许读取通讯录
{
"subject": "pkg:com.example.reader",
"object": "data:contacts",
"operation": "read",
"effect": "allow"
}
你想想看,规则越具体越好。但要注意,规则太多会影响性能。我建议把规则缓存成HashMap,主体和客体都用整数ID代替字符串。
2.4.2 策略(Policy)
策略是一组规则的容器,外加一个冲突解决机制。比如:
| 策略属性 | 取值示例 | 说明 |
|---|---|---|
| rules | 规则列表 | 包含多条具体的 allow/deny 规则 |
| defaultEffect | deny | 没有匹配时默认禁止(安全第一) |
| conflictResolution | deny-overrides 或 allow-overrides | 当多条规则冲突时,拒绝优先还是允许优先 |
| combineAlg | first-match / prioritize / cascading | 规则组合方式 |
注意:策略的默认行为千万别设成“allow”,那等于所有App都可以随便取数据。我早期一个版本就是默认允许,结果灰度测试时被安全团队当场喊停。一定用“deny by default”!
讲完这些基本概念,为了方便你理解它们之间的关系,我画了一张结构图。你看一遍应该就能记住。
你看,主体、客体、操作三个兄弟一起喂给规则,规则再喂给策略,策略最终输出权限判定。顺序很清楚。
2.5 实战中的常见模型
咱们SDK里一般不会裸用三元组,而是封装成更高层的模型。我简单列两个:
- ACL(访问控制列表):每个客体挂一个列表,列出哪些主体可以做什么。适合客体数量少、主体数量多的场景。我曾在接触者数据模块用过,因为数据项就那么几个,但接入方很多。
- RBAC(基于角色的访问控制):主体不直接绑规则,而是通过角色间接获取权限。适合权限层次复杂的SDK。比如“付费用户”角色可以读更多数据。不过要注意角色继承不能死循环,我踩过这个坑。
我的建议:初期先用ACL,简单直观;等权限规则膨胀到上百条时再切换到RBAC。别一开始就上复杂的模型,不然你自己都搞不清楚谁有什么权限。
2.6 权限判定的核心步骤
你可以把整个判定过程想象成一个流水线:
- 提取主体身份(签名、包名、UID)
- 定位目标客体(根据请求的资源路径)
- 确认操作类型(read / write / execute等)
- 加载对应策略(按客体或按主体加载)
- 逐条匹配规则,直到命中第一条或达到默认结果
- 返回允许/拒绝,并记录审计日志
嗯,这里有个细节要注意:审计日志最好记录“拒绝”的触发规则。我曾经为了调试一个权限问题,翻了一天的日志才发现是某条规则写得太宽泛。
掌握好这四个基础概念,后面讲“授权模型”和“最小权限原则”的时候你就会觉得很轻松。它们就是整个课程的基石。