多租户 SaaS 平台里,技术选型通常先定「共享库还是每租户独立库」。但无论选哪种,都有一个更容易被忽略的面:管理身份的数据库权限边界——尤其是"租户的业务管理员"与"平台的数据库集群"之间那条线。我们做了一轮系统性收敛,过程比结论更值得记录。
风险到底在哪
把"租户管理员可能越界触碰数据库"展开成具体类别,问题才可测:
- 跨库读写:租户侧身份能连到别的租户库、控制面库,读到不属于自己的数据;
- 对象级破坏:能执行建表/删表这类结构操作——一次误操作就是数据事故;
- 会话级干预:能终止其他库的会话(强制下线别人的连接);
- 权限外溢:能给自己或他人扩权,绕开既定边界。
这四类里,真正危险的是 1 和 3:它们不需要恶意,一个"顺手写死的运维脚本"就足以造成跨库影响。
第一步:先把权限矩阵画出来
收敛从盘点开始:列出全部会接触数据库的身份(应用进程、运维脚本、各层级管理员),再列出每个数据库(每个租户库、控制面库、平台库),逐格标注需要的操作——只读、读写、建表、删表、建会话、终止会话。
矩阵画完,问题一眼可见:多个本应只在自己的库里活动的身份,实际拿着能跨库读写、甚至能删库的权限——因为它们复用了同一套高权限账号。"复用高权限账号"是多租户系统里最典型的省事债。
第二步:按最小权限逐条收紧
原则只有一条:任何身份对任何数据库的权限,以"刚好够用"为上限。落地时按类别对照:
| 身份类别 | 允许 | 不允许 |
|---|---|---|
| 租户侧业务管理员 | 本租户库内业务操作 | 任何数据库级动作、任何跨库访问 |
| 只读巡检脚本 | 读元数据与指标 | 写操作、会话终止 |
| 变更执行脚本 | 指定库内的变更操作 | 未列入清单的库 |
| 平台级操作 | 受控入口 + 全程留痕 | 交互式直接操作生产 |
两个容易被忽略的细节:巡检与变更分离——日常巡检不应该持有写权限,否则一次脚本走神就是变更事故;会话能力显式授权——"终止会话"这类能力默认不附带在业务身份上,需要时单独授予、单独审计。
第三步:用独立复核验证,而不是"改完就算数"
权限收敛最怕"配置改完就算数"。我们给每条"不应有"的权限点写了验证——以该身份实际执行一次越界操作,要求被明确拒绝(而不是恰好因为你没试而存在)。验证之上还有两道:
- 独立复核:由未参与实施的人按矩阵重跑一遍测试——实施者自证不构成验证;
- 验收基线:矩阵与测试进入回归清单,新增身份或数据库时,先过矩阵再谈上线;发版后定期重跑,防止权限随迭代悄悄回涨。
小结
多租户隔离不是一个开关,而是一份需要持续维护的权限矩阵。把"谁能碰到哪个库"当成产品的一部分来管理——每条边界都有测试、有复核人、有回归——比事后补漏洞便宜得多,尤其是在租户数量增长之后。
