隔离的三层含义
自助平台把资源创建能力交到业务用户手里,隔离就成了前提。完整隔离分三层:认证解决「你是谁」,授权解决「你能执行哪些动作」,资源归属解决「你能对谁做」。前两层常用角色模型表达,第三层必须落到数据上——每条资源都要带租户、项目与环境标记,查询和操作都按标记过滤。任何一层缺失,越权都会出现。
基本信息
| 隔离维度 | 租户、项目、环境(生产与测试)、资源标签 |
|---|---|
| 授权模型 | 角色模型为主,资源属性约束用属性策略补充 |
| 执行身份 | 以申请人身份或受限服务身份调用,避免共享超级账号 |
| 默认策略 | 默认拒绝,按需授权,权限定期复核与回收 |
| 审计要求 | 记录主体、租户与目标资源归属三者 |
典型使用场景
- 多部门或多子公司共用一套平台:彼此看不到对方的资源与账单
- 外部供应商与外包人员接入:仅放开约定资源与最短有效期
- 生产与测试环境隔离:测试角色默认不能在生产提交变更
- 租户管理员自助管理:自行维护本租户成员,但不能越界到其他租户
- 成本分摊:按租户维度统计资源用量,避免标签缺失导致无法归集
隔离面与失效点
| 隔离面 | 实现手段 | 常见失效点 |
|---|---|---|
| 界面 | 按角色渲染菜单与资源列表 | 只隐藏按钮,接口仍可被直接调用 |
| 接口 | 服务端强制按租户过滤查询条件 | 按 ID 取详情时未校验归属,形成水平越权 |
| 数据 | 租户字段过滤,或独立库与独立 Schema | 聚合报表跨租户统计漏加过滤 |
| 执行 | 以请求者身份调用下游接口 | 用共享高权账号执行,动作无法归属到人 |
| 配额 | 按租户设置资源量与金额上限 | 只在前端校验,绕过前端即失效 |
服务端校验最小写法
服务端校验最小写法
# 每次请求先定租户上下文,再做动作判断
context: {tenant: from_token, user: from_token, env_scope: from_role}
allow_if:
- resource.tenant == context.tenant # 资源归属校验,缺这一条就是水平越权
- action in role_permissions[context.role] # 动作级授权
- resource.env in context.env_scope # 生产环境单独白名单
default: deny # 默认拒绝,新接口不写策略即不可用
audit: 记录 tenant/user/action/resource/result # 责任可归属角色模型管「能做什么动作」,资源归属管「能对谁做」。两者正交,任一缺失都会留下越权面;新增接口时最容易漏的正是归属校验。
水平越权最常见也最隐蔽:接口按资源 ID 取详情而不校验租户,改一个数字就能读到别的租户资源。所有以 ID 为主键的读与写接口都要带归属校验,并在测试用例中显式覆盖跨租户访问。