概述
当授权只存在于应用代码时,一处遗漏的 WHERE 或一次直连 psql 就可能暴露所有租户。把租户谓词下沉到数据库策略,让纵深防御不依赖每位开发者都记得加过滤条件。
关键步骤
- 在每个租户表上启用行级安全。
- 创建允许 tenant_id 与会话设置匹配的行的策略。
- 以会话局部设置在每个事务中写入租户 id。
- 启用 FORCE ROW LEVEL SECURITY,使表属主也受策略约束。
验证
- 应用角色只能看到当前租户的行。
- 切换租户设置后可见行随之变化。
- 表属主同样无法绕过策略。
- 缺少过滤的查询不会泄露其他租户。
注意事项
- 超级用户与 BYPASSRLS 角色会绕过策略,应使用专用非超级用户应用角色。
- 池化连接上设置可能泄漏,应在事务内用 SET LOCAL 或在取出时重置。
适用范围
本条目围绕「在 Postgres 中启用行级安全」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON orders
USING (tenant_id = current_setting('app.tenant_id')::uuid)
WITH CHECK (tenant_id = current_setting('app.tenant_id')::uuid);