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):按主体存储,每个主体维护一个 (客体, 权限) 列表。
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)的架构模式。