访问控制 RBAC / ABAC 总览待审核
应用 · 现实里的同一个元组

现实世界:XACML / AWS IAM / OPA / Cedar 都是这个函数

01–05 页那套 decide(who, when/where, what, action) → policy 不是教学虚构。 主流授权系统全都是它的实例,只是术语、语法、组合算法各有取舍。认出这层同构,阅读任何框架文档都会容易得多。

who when/where what action

函数住在哪:PEP · PDP · PAP · PIP

把判定从业务代码里抽出来,是这套架构的第一性原理。四个角色 (XACML 命名,已成行业通用语):

PEP
Policy Enforcement Point。挡在资源前的关卡 (中间件 / API 网关):装配授权请求、调用 PDP、执行它的裁决 (放行 / 拦截 / 履行 obligation)。
PDP
Policy Decision Point。就是 decide() 函数本身:接收请求、运行规则、按组合算法给出 permit/deny。它不碰业务,只做判定。
PAP
Policy Administration Point。写规则、管规则的地方 (策略后台 / 配置仓库)。规则从这里下发给 PDP。
PIP
Policy Information Point。判定时缺的属性 (用户密级、资源 owner、风险分) 从这里现取 —— 供给 PDP 的「属性数据源」。
一句话:PEP 拦、PDP 判、PAP 配、PIP 供数。01–05 页的 demo 全是 PDP 这一格; policy.js 里写死的 SUBJECTS / RESOURCES 就是 PIP 的角色。

XACML —— 四个轴的「教科书原型」

OASIS 的 XACML 把请求显式分成四个 category,几乎和本系列一一对应。它还贡献了 PEP/PDP 术语、 Permit/Deny/NotApplicable/Indeterminate 四态结果,以及一整套组合算法 (deny-overrides / permit-overrides / first-applicable / ordered-…)。XML 语法冗长,但模型是地基。

本系列XACML category
whoSubject (access-subject)
actionAction
whatResource
when/whereEnvironment

AWS IAM —— 云上使用最广泛的策略引擎

每条 IAM policy 就是这四个轴:Principal(who)、ActionResource(what)、 Condition(when/where)。它的组合规则是行业经典:默认拒绝;显式 Allow 才放行; 任何显式 Deny 永远赢 —— 也就是本系列的 deny-overrides + closed world。

iam-policy.json 「财务组只能在工作时段、从公司 IP 读预算桶」
// Effect=Deny 会盖过任何 Allow (deny-overrides)
{
  "Effect": "Allow",
  "Principal": { "AWS": "role/Finance" },        // who
  "Action":   ["s3:GetObject"],                  // action
  "Resource": "arn:aws:s3:::budgets/*",          // what
  "Condition": {                                  // when/where
    "IpAddress":   { "aws:SourceIp": "10.0.0.0/8" },
    "DateGreaterThan": { "aws:CurrentTime": "...T09:00:00Z" }
  }
}

OPA / Rego —— 把策略当成「数据上的查询」

Open Policy Agent 用 Rego 语言,请求统一放进 input:input.user / input.action / input.resource。它的代表性写法是 default allow := false —— 显式声明 closed world,再用若干 allow { ... } 规则累加放行理由 (任一成立即 permit,即 permit-overrides)。

authz.rego
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
}

Cedar —— 读起来就是「四元组 + when」

AWS 后来开源的 Cedar (Verified Permissions 背后的语言) 把这套写得最像自然语言: permit(principal, action, resource) 三个参数直接构成函数签名,情境放进 when { context.* }。 它还能被形式化验证,适合做细粒度的对象级授权。

policy.cedar
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 分支

四种「BAC」:同一个函数,看哪些参数

各种 access control 模型的差别,本质就是这个函数允许看哪几个参数、用什么形状的规则:

模型规则主要看一句话
RBACwho.role角色→权限查表。简单、可审计,但表达不了情境与「自己的」。
ABACwho / what / when 的任意属性规则是属性的布尔表达式。最灵活,本系列主线;代价是难审计、难穷尽。
ReBACwho 与 what 之间的关系「owner / member / parent」这类图上的边。Google Zanzibar、GitHub 协作权限。
PBAC集中式 policy (常 = ABAC)强调「策略与代码分离、统一治理」的工程视角,XACML/OPA/Cedar 都归这一类。
它们不互斥:真实系统常是「RBAC 定粗粒度角色 + ABAC/ReBAC 加情境与对象级细化」的混合。
核心结论:无论框架叫什么,授权永远是 decide(who, when/where, what, action) → permit/deny (+obligations)。 搭建权限系统时,先把这四个输入组合算法 + 默认决策定清楚,再选工具 —— 模型正确,实现可以替换。

相关链接