第1章 多租户场景与RBAC核心概念

多租户(Multi-Tenancy)与基于角色的访问控制(RBAC)天然互补:租户定义了资源与用户的逻辑边界,RBAC提供了边界内的权限组织方式。本章明确租户、角色、权限、会话、隔离需求这五个核心概念在架构中的位置与关系,为后续29章的分层设计、控制链路和落地验收建立统一术语基础。

1.1 核心概念定义

概念架构定义在多租户场景中的角色
租户一组隔离的用户、数据和配置的逻辑集合权限边界:不同租户的用户即使同名角色也无权访问对方资源
角色一组权限的命名集合,可被授予用户或用户组租户内的权限组合单位,支持层级继承和叠加
权限对特定资源执行特定操作(增/删/改/查)的许可由租户资源域限定,通常表达为 资源类型:操作
会话用户激活的角色子集及上下文控制用户同时拥有的有效权限范围,最小化误操作风险
隔离需求租户之间在数据、配置、运行时层面的完全或部分隔离决定RBAC策略的存储方式(共享表+租户ID vs 独立数据库)
架构提示:在多租户RBAC设计中,租户是最高层级的分区键。角色和权限的名称可以在不同租户间重复,但通过 tenant_id 字段实现逻辑隔离。

1.2 边界:多租户RBAC vs 传统RBAC

传统RBAC假设所有用户、角色、权限属于同一安全域;多租户RBAC则引入 租户边界,使得同一个RBAC引擎需要处理N个并行的权限空间。核心差异体现在三个维度:

  • 角色命名空间:传统RBAC中角色全局唯一;多租户中角色名可跨租户重复,由 tenant_id 区分。
  • 权限资源标识:传统RBAC用 resource:action;多租户需附加租户前缀,例如 tenant_42:document:read。
  • 会话范围:传统RBAC会话仅包含角色ID列表;多租户会话必须携带当前租户标识,并限制用户只能激活本租户内的角色。

1.3 分层架构视图

多租户RBAC模型在控制层面分为四层(自底向上):资源层 → 权限定义层 → 角色映射层 → 会话/策略执行层。每一层都受租户隔离机制的约束。

多租户RBAC核心概念关系图 多租户RBAC核心概念关系 租户边界(逻辑容器) 租户 角色 权限 会话 隔离需求 拥有 包含 关联 激活 限定于 约束 租户边界 虚线表示逻辑隔离

1.4 组件职责与信任链路

多租户RBAC的核心组件围绕 策略决策点(PDP) 和 策略执行点(PEP) 展开,额外引入 租户上下文解析器 来维护隔离边界。

组件职责在多租户中的特殊要求
PEP(策略执行点)拦截请求,提取用户、资源、动作及租户标识必须从请求头或JWT中解析 X-Tenant-ID
PDP(策略决策点)根据角色-权限映射做出允许/拒绝决策决策时先验证租户合法性,再查角色映射
PIP(策略信息点)提供用户-角色、角色-权限、会话状态数据查询语句必须带 WHERE tenant_id = ?,防止跨租户数据泄露
PAP(策略管理点)管理角色定义、权限分配、租户配置提供租户管理员的角色编辑面板,限制超管操作范围
控制流示例(授权请求):
用户请求 → PEP提取 tenant_id & user_id → PDP调用PIP获取该租户下的用户角色 → PDP计算权限 → 返回Allow/Deny → PEP执行。

1.5 选型权衡:集中式 vs 分散式租户角色管理

  • 集中式:所有租户共享同一张角色表,通过 tenant_id 过滤。优势:运维简单,利于全局审计;风险:单表大时性能下降,且容易因SQL拼写错误导致跨租户数据泄露。
  • 分散式:每个租户拥有独立的角色表(甚至独立数据库)。优势:强隔离,可独立扩缩;劣势:管理成本高,跨租户角色复制困难。
风险警告:如果选择集中式模型,必须强制PIP层所有查询使用预编译参数绑定,禁止拼接 WHERE tenant_id='{input}'。历史上发生过因字符串注入导致的租户间越权事故。

1.6 落地步骤(第1周关键动作)

  1. 识别租户维度:确定是组织(企业)、项目还是个人作为租户单元。
  2. 定义租户标识策略:使用UUID还是递增整数?建议UUID以避免枚举攻击。
  3. 设计角色命名规则:如 {租户类型}_{作用域}_{级别},避免碰撞。
  4. 初始化隔离层级:在基础设施中明确租户ID的传递方式(HTTP头、JWT claim、gRPC元数据)。
  5. 编写最小可行PEP拦截器:先做日志记录,不做实际授权,用于验证租户上下文是否完整。

1.7 验收标准

  • 每个授权请求都能正确携带租户标识,且服务端可解析。
  • 跨租户请求(URL或 payload 中修改租户ID)被显式拒绝。
  • 角色-权限映射只在同一租户内生效,切换租户后角色列表清空。
  • 会话激活时,不能激活其他租户的角色。
  • 权限审计日志包含 tenant_id 字段,可追溯至具体租户。