策略语言介绍:三大主流选手

说到访问控制策略,绕不开的就是怎么描述它。说白了,策略语言就是给机器看的「权限说明书」。我自己这些年折腾过不少系统,从传统企业级到云原生,见过太多因为策略表述不清导致的安全事故。

今天咱们就聊聊三个主流选手:XACML、ALFA 和 AWS IAM Policy。了解它们,你基本能搞定 80% 的场景。

XACML – 老牌选手,能打但啰嗦

XACML(eXtensible Access Control Markup Language)是 OASIS 的标准。我最早接触它是在一家银行的权限系统里,那时候我才知道,原来策略可以写得像文言文一样长。

它的核心思想是 PDP/PEP/PIP/PRP 四大组件:

  • PEP(策略执行点):收到访问请求,拦截下来问PDP。
  • PDP(策略决策点):查策略库,算结果(Permit/Deny/NotApplicable)。
  • PIP(策略信息点):用户角色、资源属性等上下文数据。
  • PRP(策略管理点):存策略的地方。

举个例子,一个简单的策略用 XACML 长这样:

<Policy PolicyId="sample" RuleCombiningAlg="deny-unless-permit">
  <Target>
    <AnyOf>
      <AllOf>
        <Match MatchId="string-equal">
          <AttributeValue DataType="string">read</AttributeValue>
          <AttributeDesignator AttributeId="action-id"/>
        </Match>
      </AllOf>
    </AnyOf>
  </Target>
  <Rule Effect="Permit">
    <Condition>
      <Apply FunctionId="string-equal">
        <AttributeValue DataType="string">admin</AttributeValue>
        <AttributeDesignator AttributeId="subject-role"/>
      </Apply>
    </Condition>
  </Rule>
</Policy>
我曾经踩过的坑: 用 XACML 写一个含 5 个条件的大策略,XML 嵌套了 7 层,人眼根本看不出逻辑对不对。而且不同厂商的 PDP 实现细节有差异,同一份策略在 SunXACML 和 AuthzForce 上的执行结果居然不一样。所以啊,别迷信标准。

ALFA – 更适合码农的方言

ALFA(Axiomatics Language for Authorization)本质上是 XACML 的简化版,但它用了类 Java 的语法。我个人觉得,如果你团队里都是开发人员,用 ALFA 比直接写 XML 舒服太多了。

同样的策略,ALFA 写法:

namespace myapp {
  policy sample {
    target clause actionId == "read"
    apply denyUnlessPermit
    rule allowAdmin {
      condition subjectRole == "admin"
      permit
    }
  }
}

你看,连尖括号都没了。ALFA 编译后生成标准的 XACML,所以底层还是同一套东西。我参与过的一个 SaaS 项目就用 ALFA 写了 200 多条策略,配合 Git 做版本管理,比直接改 XML 靠谱多了。

小建议: 如果你的策略需要业务人员审核,还是别用 ALFA 了。业务老大看到这种代码会直接扔回给你的。给他们准备个可视化界面更实际。

AWS IAM Policy – 云上王者

AWS IAM Policy 是 JSON 格式的策略语言。说实话,现在很多云原生架构都在模仿它。它的结构非常清晰:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*",
      "Condition": {
        "IpAddress": { "aws:SourceIp": "203.0.113.0/24" }
      }
    }
  ]
}

关键要素就四个:

  • Effect:Allow 还是 Deny(Deny 优先级更高)
  • Action:服务+操作,比如 ec2:StartInstances
  • Resource:要控制的资源 ARN,支持通配符
  • Condition:附加条件,比如限制 IP、时间、MFA 状态

实际生产里最坑的是 通配符滥用。我见过有人写 "Resource": "*" 然后开了一大堆 Action,结果一台被攻陷的 EC2 直接把整个 S3 桶删了。AWS 的 Deny 优先级高,但如果你没写 Deny,到处都是 Allow 通配符,那就等于没防护。

三张策略语言的对比

维度XACMLALFAAWS IAM Policy
语法风格XML(臃肿)类 Java(简洁)JSON(轻量)
设计理念ABAC/RBAC 通用同 XACML资源型 + 条件
执行机制PDP/PEP 分离编译为 XACML内置在 AWS 服务
复杂度高(学习曲线陡)中低(5分钟上手)
适用场景大型企业、跨系统开发团队主导AWS 环境、云原生

我的选择策略:

  • 如果系统需要对接多个异构平台,用 XACML 做标准层。
  • 如果团队全是 Java/Go 开发,用 ALFA 写策略然后编译。
  • 如果就是玩 AWS,果断选 IAM Policy,别瞎折腾。

其他值得一提的语言

当然,不只有这三个。比如 Open Policy Agent (OPA) 用的 Rego,它完全是声明式逻辑,适合 Kubernetes、微服务场景。还有 Kubernetes RBAC 的 YAML 策略、Google Cloud IAM 的 Policy 架构。说实话,万变不离其宗:定义谁(Subject)在什么条件(Condition)下对什么资源(Resource)能干什么(Action)。

但你要想自动化推导策略,选对语言很重要。我建议刚开始做项目时先别纠结语法,而是把要表达的策略元素搞清楚:用户、资源、动作、环境。语言只是载体。

三种策略语言核心理念对比 XACML (XML) PDP → PEP → PIP ABAC / RBAC 通用 企业级、跨系统 ALFA (类 Java) 编译为 XACML 开发人员友好 Git 版本管理 AWS IAM Policy (JSON) Effect/Action/Resource 内置 AWS 服务执行 Deny 优先级高 三者本质相同:描述谁在什么条件下对什么资源做什么 区别在于语法、生态和学习成本,选择取决于团队和平台