2. 权限矩阵基础:RBAC模型回顾、ABAC模型简介、权限矩阵的数学表示与存储结构

在CI/CD流水线中,每一次构建、测试、部署都涉及对代码仓库、制品库、基础设施凭证、环境变量的访问。权限矩阵是描述“谁(主体)能对什么(资源)执行哪些操作(动作)”的数学结构。本节从经典模型出发,逐步过渡到矩阵的数学表示与工程存储。

2.1 RBAC模型回顾

基于角色的访问控制(RBAC)是当前企业级权限管理的事实标准。其核心思想是将权限授予角色,再将角色授予用户,实现用户与权限的逻辑解耦。

RBAC核心要素

要素 定义 CI/CD场景示例
用户(User) 访问系统的自然人/服务账号 jenkins-bot、developer-zhang
角色(Role) 权限的集合,具有语义化名称 ci-admin、deploy-operator、read-only
权限(Permission) 对特定资源的操作许可 k8s:deploy、artifact:push、secret:read
会话(Session) 用户激活的角色实例 流水线执行时绑定的临时凭证

RBAC关系模型

标准RBAC(NIST INCITS 359-2004)定义了以下关系:

  • 用户-角色分配(UA):多对多关系,一个用户可拥有多个角色,一个角色可被多个用户拥有。
  • 角色-权限分配(PA):多对多关系,一个角色包含多个权限,一个权限可被多个角色包含。
  • 角色层级(RH):高级角色继承低级角色的权限,例如 ci-admin 继承 deploy-operator 的所有权限。
  • 约束(Constraint):职责分离(SoD),例如同一用户不能同时拥有“创建发布”和“审批发布”角色。
💡 CI/CD实践要点: 在流水线中,服务账号(Service Account)应遵循最小权限原则。例如,构建阶段仅需 code:read 和 artifact:write,不应授予 k8s:deploy 权限。

2.2 ABAC模型简介

基于属性的访问控制(ABAC)通过评估主体、资源、环境的一组属性来动态判定权限,解决了RBAC在细粒度、上下文敏感场景下的不足。

ABAC核心属性维度

属性类别 示例属性 CI/CD场景值
主体属性 用户ID、部门、安全等级、角色 user:deploy-bot, team:platform, clearance:L3
资源属性 资源类型、环境标签、数据分类 type:namespace, env:production, classification:critical
环境属性 时间、IP范围、网络区域、流水线阶段 time:09:00-18:00, ip:10.0.0.0/8, stage:deploy
操作属性 动作类型、幂等性、风险等级 action:delete, idempotent:false, risk:high

ABAC策略示例(伪代码)

// 仅允许在非生产环境、工作时间、由平台团队执行部署操作
policy "safe-deploy" {
  effect = "Allow"
  condition {
    subject.team == "platform"
    resource.env != "production"
    environment.time between "08:00" and "20:00"
    action.name == "deploy"
  }
}
📌 模型选择建议: 在CI/CD流水线中,建议采用RBAC + ABAC混合架构。RBAC负责粗粒度的角色划分(如管理员、开发者、只读),ABAC负责细粒度的动态条件(如仅允许在非生产环境执行部署、仅允许在代码审查通过后合并)。

2.3 权限矩阵的数学表示

权限矩阵(Access Matrix)是描述整个系统授权状态的数学模型。设主体集合为 S,客体集合为 O,操作集合为 A,则权限矩阵 M 是一个 |S| × |O| 的矩阵,其中每个元素 M[s][o] 是 A 的一个子集。

形式化定义

M : S × O → 2^A

其中:
  S = {s₁, s₂, ..., sₘ}  // 主体集合
  O = {o₁, o₂, ..., oₙ}  // 客体集合
  A = {read, write, execute, delete, deploy, approve}  // 操作集合
  M[s][o] ⊆ A  // 主体s对客体o拥有的操作权限

矩阵示例

主体 \ 客体 代码仓库:frontend 制品库:release K8s集群:prod 密钥管理:db-pass
ci-bot {read} {read, write} {read} {read}
deploy-bot {read} {read} {read, deploy} {read}
security-auditor {read} {read} {read} {read, audit}

矩阵的稀疏性与优化

在实际系统中,|S| 和 |O| 可能达到数万甚至百万级别,全量矩阵存储不可行。工程上通常采用以下优化:

  • 基于角色的矩阵压缩:将用户聚合为角色,存储 |Role| × |O| 矩阵。
  • 访问控制列表(ACL):按客体存储,每个客体维护一个 (主体, 权限) 列表。
  • 能力列表(Capability):按主体存储,每个主体维护一个 (客体, 权限) 列表。
权限矩阵的三种工程存储结构对比 ACL(访问控制列表) 按客体组织 客体: K8s集群:prod ├─ ci-bot: {read} ├─ deploy-bot: {read,deploy} └─ auditor: {read} 能力列表(Capability) 按主体组织 主体: deploy-bot ├─ code:frontend: {read} ├─ artifact:release: {read} └─ k8s:prod: {read,deploy} RBAC角色矩阵 按角色压缩 角色: deploy-operator ├─ code:frontend: {read} ├─ artifact:release: {read} └─ k8s:prod: {read,deploy} 存储结构选择策略 • ACL:适合客体数量少、主体数量多的场景(如文件系统、K8s Namespace权限) • Capability:适合主体数量少、客体数量多的场景(如微服务间调用凭证) • RBAC矩阵:适合角色层级清晰、权限变更频繁的企业级应用 • 混合方案:CI/CD流水线中,推荐ACL管理环境级权限 + RBAC管理角色级权限

2.4 权限矩阵的存储结构

在数据库层面,权限矩阵通常采用关系模型或文档模型存储。以下是两种主流存储方案。

关系型存储(PostgreSQL示例)

-- RBAC核心表结构
CREATE TABLE users (
  id UUID PRIMARY KEY,
  name VARCHAR(128) NOT NULL,
  type VARCHAR(32) CHECK (type IN ('human', 'service_account'))
);

CREATE TABLE roles (
  id UUID PRIMARY KEY,
  name VARCHAR(128) UNIQUE NOT NULL,
  parent_role_id UUID REFERENCES roles(id)  -- 角色层级
);

CREATE TABLE permissions (
  id UUID PRIMARY KEY,
  resource VARCHAR(256) NOT NULL,  -- 例如: k8s:namespace:prod
  action VARCHAR(64) NOT NULL      -- 例如: deploy
);

CREATE TABLE user_role_assignments (
  user_id UUID REFERENCES users(id),
  role_id UUID REFERENCES roles(id),
  PRIMARY KEY (user_id, role_id)
);

CREATE TABLE role_permission_assignments (
  role_id UUID REFERENCES roles(id),
  permission_id UUID REFERENCES permissions(id),
  PRIMARY KEY (role_id, permission_id)
);

文档型存储(MongoDB示例)

// 用户文档内嵌权限矩阵(适用于Capability模式)
{
  "_id": "deploy-bot",
  "type": "service_account",
  "capabilities": [
    { "resource": "code:frontend", "actions": ["read"] },
    { "resource": "artifact:release", "actions": ["read", "write"] },
    { "resource": "k8s:prod", "actions": ["read", "deploy"] }
  ]
}

// 策略文档(适用于ABAC扩展)
{
  "policy_id": "safe-deploy",
  "effect": "Allow",
  "conditions": {
    "subject.team": "platform",
    "resource.env": { "$ne": "production" },
    "environment.time": { "$gte": "08:00", "$lte": "20:00" }
  }
}
⚠️ 性能与安全注意事项:
  • 权限矩阵的查询必须走索引,避免全表扫描导致流水线延迟。
  • 对于高频访问的权限判定(如每次构建前的凭证获取),建议使用Redis缓存权限矩阵的快照。
  • 矩阵变更应记录审计日志,包括变更时间、操作人、变更前后内容。
  • 避免在矩阵中存储明文敏感信息(如密码、Token),仅存储资源引用ID。

2.5 从矩阵到动态校验的桥梁

静态权限矩阵定义了“允许做什么”,而动态校验需要回答“在当前上下文中是否允许执行”。这需要引入策略执行点(PEP)和策略决策点(PDP)的架构模式。

权限矩阵在动态校验中的位置 流水线请求 (主体+资源+动作) PEP 策略执行点 PDP 策略决策点 权限矩阵 (RBAC/ABAC策略) Allow / Deny