# 第十六章:策略即代码(Policy as Code) > "策略不应该藏在配置文件里,它应该像代码一样被版本控制、测试和审计。" ```{mermaid} 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 开源的策略语言,语法直观: ```text // 允许管理员执行所有操作 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 ```text // 定义实体类型和关系 entity User { department: String, clearance: Long, }; entity Team { members: Set, }; 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 模型定义 ```ini # 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 示例 ```python 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 策略管理 ```yaml # .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** 实现策略的自动化测试和部署