第十六章:策略即代码(Policy as Code)

“策略不应该藏在配置文件里,它应该像代码一样被版本控制、测试和审计。”

        mindmap
  root((策略即代码))
    理念
      版本控制
      测试
      审计
      GitOps
    策略引擎
      OPA/Rego
      Cedar
      Casbin
      OpenFGA DSL
    Cedar
      permit/forbid
      Entity
      Schema
    Casbin
      PERM 元模型
      Adapter
      多模型
    

16.1 策略即代码的理念

策略即代码(Policy as Code)将安全策略从手动配置转变为可编程、可测试、可审计的代码:

传统方式:
┌──────────┐    ┌──────────┐    ┌──────────┐
│  管理员   │───▶│ 管理界面  │───▶│ 配置文件  │
│ 手动配置  │    │ 点击操作  │    │ 难以追踪  │
└──────────┘    └──────────┘    └──────────┘

策略即代码:
┌──────────┐    ┌──────────┐    ┌──────────┐    ┌──────────┐
│  开发者   │───▶│  Git     │───▶│  CI/CD   │───▶│ 策略引擎  │
│ 编写策略  │    │ 版本控制  │    │ 测试+部署 │    │ 自动生效  │
└──────────┘    └──────────┘    └──────────┘    └──────────┘
     │               │               │               │
     ▼               ▼               ▼               ▼
  代码审查       变更历史        自动化测试       审计日志

核心原则

原则

说明

版本控制

策略存储在 Git 中,每次变更有完整历史

代码审查

策略变更需要 PR 审查,至少两人批准

自动化测试

策略有单元测试和集成测试

持续部署

通过 CI/CD 自动部署策略变更

审计追踪

谁在什么时候改了什么策略,一目了然

环境一致

开发、测试、生产使用相同的策略代码

16.2 策略引擎对比

引擎

语言

模型

开源

适用场景

OPA

Rego

ABAC

✅ CNCF

K8s、API、通用

Cedar

Cedar

ABAC+RBAC

✅ Apache

AWS、应用授权

Casbin

PERM DSL

多模型

✅ Apache

多语言应用

OpenFGA

FGA DSL

ReBAC

✅ CNCF

协作应用、SaaS

16.3 Cedar 语言

Cedar 是 AWS 开源的策略语言,语法直观:

// 允许管理员执行所有操作
permit (
    principal in Role::"admin",
    action,
    resource
);

// 允许用户查看自己的文档
permit (
    principal,
    action == Action::"view",
    resource
) when {
    resource.owner == principal
};

// 禁止在非工作时间访问机密文档
forbid (
    principal,
    action,
    resource
) when {
    resource.classification == "confidential" &&
    !(context.time.hour >= 9 && context.time.hour < 18)
};

// 允许团队成员编辑团队文档
permit (
    principal,
    action == Action::"edit",
    resource is Document
) when {
    principal in resource.team.members
};

Cedar Schema

// 定义实体类型和关系
entity User {
    department: String,
    clearance: Long,
};

entity Team {
    members: Set<User>,
};

entity Document {
    owner: User,
    team: Team,
    classification: String,
};

action "view" appliesTo {
    principal: User,
    resource: Document,
};

action "edit" appliesTo {
    principal: User,
    resource: Document,
};

AWS Verified Permissions

AWS Verified Permissions 是基于 Cedar 的托管授权服务:

应用 ──▶ AWS Verified Permissions ──▶ 决策
              │
              ├── Cedar 策略
              ├── 实体数据(Cognito 集成)
              └── 审计日志(CloudTrail)

16.4 Casbin

Casbin 支持多种访问控制模型,通过 PERM 元模型定义:

PERM 元模型

P = Policy(策略定义)
E = Effect(效果组合)
R = Request(请求定义)
M = Matchers(匹配规则)

RBAC 模型定义

# model.conf
[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act

Python Casbin 示例

import casbin

# 创建 enforcer
e = casbin.Enforcer("model.conf", "policy.csv")

# policy.csv 内容:
# p, admin, /api/users, GET
# p, admin, /api/users, POST
# p, admin, /api/users, DELETE
# p, editor, /api/documents, GET
# p, editor, /api/documents, PUT
# p, viewer, /api/documents, GET
# g, alice, admin
# g, bob, editor
# g, carol, viewer

# 检查权限
print(e.enforce("alice", "/api/users", "DELETE"))    # True (admin)
print(e.enforce("bob", "/api/documents", "PUT"))     # True (editor)
print(e.enforce("carol", "/api/documents", "PUT"))   # False (viewer)

# 动态添加策略
e.add_policy("editor", "/api/comments", "POST")
e.add_grouping_policy("dave", "editor")

# FastAPI 集成
from fastapi import FastAPI, Depends, HTTPException, Request

app = FastAPI()

async def casbin_authorize(request: Request):
    user = get_current_user(request)
    path = request.url.path
    method = request.method
    if not e.enforce(user.username, path, method):
        raise HTTPException(status_code=403, detail="Access denied")
    return user

@app.get("/api/documents")
async def list_documents(user=Depends(casbin_authorize)):
    return {"documents": [...]}

16.5 策略引擎选型决策树

你的需求是什么?
│
├── 需要 Kubernetes Admission Control?
│   └── ✅ OPA Gatekeeper
│
├── 需要多语言支持(Go/Java/Python/Node)?
│   └── ✅ Casbin
│
├── 使用 AWS 生态?
│   └── ✅ Cedar + AWS Verified Permissions
│
├── 需要资源级细粒度权限(协作应用)?
│   └── ✅ OpenFGA
│
├── 需要复杂条件逻辑(ABAC)?
│   └── ✅ OPA 或 Cedar
│
└── 简单的 RBAC?
    └── ✅ Casbin(最简单)或应用内实现

16.6 GitOps 策略管理

# .github/workflows/policy-deploy.yml
name: Deploy Policies
on:
  push:
    branches: [main]
    paths: ['policies/**']

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run OPA tests
        run: opa test policies/ -v
      - name: Validate Cedar policies
        run: cedar validate --schema schema.cedarschema --policies policies/

  deploy:
    needs: test
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to OPA
        run: |
          curl -X PUT http://opa-server:8181/v1/policies/authz \
            --data-binary @policies/authz.rego

16.7 小结

  • 策略即代码 将安全策略纳入软件工程实践:版本控制、测试、审计

  • Cedar 语法直观,适合 AWS 生态和应用级授权

  • Casbin 支持多语言和多种访问控制模型,入门简单

  • OPA 适合基础设施策略(K8s、Terraform)和复杂 ABAC

  • OpenFGA 适合关系驱动的细粒度授权

  • 通过 GitOps 实现策略的自动化测试和部署