标准答案

  1. 启用 RLS 后,策略用 USING 限制现有行是否可见或可被目标操作命中,用 WITH CHECK 限制 INSERT 或 UPDATE 后的新行是否允许写入;只写一个条件容易留下越权路径。
  2. 应用角色应只拥有必要权限,并在每个事务中设置可信的租户上下文。使用连接池时,优先使用事务级设置,事务结束后让上下文自动清理。
  3. 表所有者、超级用户和带 BYPASSRLS 属性的角色通常不受普通 RLS 策略限制;需要让表所有者也接受策略时,应评估 FORCE ROW LEVEL SECURITY 和运维流程。
  4. 租户列、策略表达式和访问路径要有配套索引,复杂策略还要测试 JOIN、聚合、分页和批处理的计划与性能。
  5. RLS 解决的是行级可见性和写入边界,不会自动解决管理员授权、跨租户报表、对象存储访问或缓存键隔离;这些边界仍需在各自系统中验证。

题目解析

RLS 的价值是把租户过滤从“每条 SQL 都记得写条件”提升为数据库策略,但策略仍然是安全边界的一部分,必须像代码权限一样进行评审、测试和审计。

连接池是最容易被忽略的风险:如果租户上下文用 session 级变量设置,却没有在归还前清理,下一个请求可能复用旧租户身份。事务级设置能缩短泄漏范围,但仍要验证异常和连接重置路径。

越权测试不能只测试 SELECT。还要覆盖 INSERT、UPDATE、DELETE、批量任务、导出、管理员工具、SECURITY DEFINER 函数和缓存,确认不存在通过另一条入口绕过策略的路径。

常见误区

  • 误区:只在应用 SQL 中拼接 tenant_id 就足够。改正:让数据库角色和 RLS 提供第二道边界,并对所有写入和导出路径做越权测试。
  • 误区:使用 session 级租户变量却不清理连接。改正:优先采用事务级上下文,且在连接池归还和异常路径验证上下文不会串租户。
  • 误区:认为启用 RLS 后连表所有者和运维账号也会自动受限。改正:核对角色属性、BYPASSRLS、SECURITY DEFINER 和 FORCE ROW LEVEL SECURITY 的实际行为。

作者信息