← 中文资源

简体中文版本

在 Postgres 中启用行级安全

启用行级安全,编写按当前租户过滤的策略,并强制策略对表属主同样生效,使隔离由数据库强制。

阅读英文原文

概述

当授权只存在于应用代码时,一处遗漏的 WHERE 或一次直连 psql 就可能暴露所有租户。把租户谓词下沉到数据库策略,让纵深防御不依赖每位开发者都记得加过滤条件。

关键步骤

  1. 在每个租户表上启用行级安全。
  2. 创建允许 tenant_id 与会话设置匹配的行的策略。
  3. 以会话局部设置在每个事务中写入租户 id。
  4. 启用 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);