现实世界:XACML / AWS IAM / OPA / Cedar 都是这个函数
前五页那套 decide(who, when/where, what, action) → policy 不是教学虚构。主流授权系统全都是它的实例,只是术语、语法、组合算法各有取舍。认出这层同构,阅读任何框架文档都会容易得多。
1 · 函数住在哪:PEP · PDP · PAP · PIP
把判定从业务代码里抽出来,是这套架构的第一性原理。四个角色由 XACML 命名,已成行业通用语:PEP 拦、PDP 判、PAP 配、PIP 供数。
注 · 本系列前五页的 demo 全是 PDP 这一格;policy.ts 里写死的 SUBJECTS / RESOURCES 就是 PIP 的角色。
2 · XACML:四个轴的教科书原型
OASIS 的 XACML 把请求显式分成四个 category,几乎和本系列一一对应。它还贡献了 PEP/PDP 术语、Permit/Deny/NotApplicable/Indeterminate 四态结果,以及一整套组合算法(deny-overrides / permit-overrides / first-applicable /
ordered-…)。XML 语法冗长,但模型是地基。
| 本系列 | XACML category |
|---|---|
| who | Subject (access-subject) |
| action | Action |
| what | Resource |
| when/where | Environment |
3 · AWS IAM:云上使用最广泛的策略引擎
每条 IAM policy 就是这四个轴:Principal(who)、Action、Resource(what)、Condition(when/where)。它的组合规则是行业经典:默认拒绝;显式 Allow 才放行;任何显式 Deny 永远赢——也就是本系列的 deny-overrides 加 closed world。
// 「财务组只能从公司 IP、在指定时间窗内读预算桶」—— S3 桶策略, 资源侧
// Effect=Deny 会盖过任何 Allow (deny-overrides)
{
"Effect": "Allow",
"Principal": { // who
"AWS": "arn:aws:iam::123456789012:role/Finance"
},
"Action": ["s3:GetObject"], // action
"Resource": "arn:aws:s3:::budgets/*", // what
"Condition": { // when/where
"IpAddress": { "aws:SourceIp": "10.0.0.0/8" },
"DateGreaterThan": { "aws:CurrentTime": "2026-01-01T09:00:00Z" },
"DateLessThan": { "aws:CurrentTime": "2026-12-31T18:00:00Z" }
}
}
两处按 IAM 的实际约束写死了。Principal 只能出现在资源侧策略里,且角色必须写完整 ARN——role/Finance 这种简写会被判为 invalid principal,账号 ID 不能省,也不允许用通配符匹配 ARN 的一部分。时间那一维则连「工作时段」都表达不了:aws:CurrentTime 比的是绝对时间点,IAM
没有「每天 9:00 到 18:00」这种周期性条件键,只能像上面那样卡一个固定窗口,或把周期性判断挪出策略之外。
4 · OPA / Rego:把策略当成数据上的查询
Open Policy Agent 用 Rego 语言,请求统一放进 input:input.user / input.action / input.resource。它的代表性写法是 default allow := false——显式声明 closed world,再用若干 allow { ... } 规则累加放行理由(任一成立即 permit,即 permit-overrides)。
package authz
default allow := false # 默认拒绝 (closed world)
# 本人拥有的资源可读改 (关系 / ReBAC)
allow if {
input.resource.owner == input.user.id # who × what
input.action in {"read", "update"} # action
}
# 读且密级足够
allow if {
input.action == "read"
input.user.clearance >= input.resource.classification
}
5 · Cedar:读起来就是四元组加 when
AWS 后来开源的 Cedar(Verified Permissions 背后的语言)把这套写得最像自然语言:permit(principal, action, resource) 三个参数直接构成函数签名,情境放进 when { context.* }。它还能被形式化验证,适合做细粒度的对象级授权。
permit (
principal in Group::"Finance", // who
action in [Action::"read", Action::"export"], // action
resource in Folder::"budgets" // what
)
when { context.ip.isInRange(ip("10.0.0.0/8")) } // when/where
unless { context.device == "personal" }; // deny 分支
6 · 四种 BAC 模型的参数差别
各种 access control 模型的差别,本质就是这个函数允许看哪几个参数、用什么形状的规则。
| 模型 | 规则主要看 | 一句话 |
|---|---|---|
| RBAC | who.role |
角色 → 权限查表。简单、可审计,但表达不了情境与「自己的」。 |
| ABAC | who / what / when 的任意属性 | 规则是属性的布尔表达式。最灵活,本系列主线;代价是难审计、难穷尽。 |
| ReBAC | who 与 what 之间的关系 | 「owner / member / parent」这类图上的边。Google Zanzibar、GitHub 协作权限,详见 ReBAC。 |
| PBAC | 集中式 policy(常等于 ABAC) | 强调「策略与代码分离、统一治理」的工程视角,XACML / OPA / Cedar 都归这一类。 |
建议 · 无论框架叫什么,授权永远是 decide(who, when/where, what, action) → permit/deny (+obligations)。搭建权限系统时,先把这四个输入和「组合算法 + 默认决策」定清楚,再选工具——模型正确,实现可以替换。
7 · 参考文献
- OASIS. eXtensible Access Control Markup Language (XACML) Version 3.0. 四个 category、PEP/PDP/PAP/PIP 与组合算法的原始出处。docs.oasis-open.org
- Amazon Web Services. Policy evaluation logic. IAM User Guide. 默认拒绝、显式 Deny 永远赢的官方判定流程图。docs.aws.amazon.com
- Open Policy Agent. Policy Language.
input与default allow := false的 policy-as-code 范式。openpolicyagent.org - Amazon Web Services. Cedar Policy Language Reference Guide.
permit(principal, action, resource) when {…}的语法定义,以及可形式化验证的依据。docs.cedarpolicy.com - Pang, R. et al. (2019). Zanzibar: Google's Consistent, Global Authorization System. USENIX ATC '19. ReBAC 的工业级代表,关系元组驱动授权。research.google