

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 行级安全建议
<a name="rls"></a>

使用 PostgreSQL 在池化模型中维护租户数据隔离需要行级安全 (RLS)。RLS 将隔离策略的实施集中在数据库级别，并消除了软件开发人员维护这种隔离的负担。实现 RLS 的最常见方法是在 PostgreSQL 数据库管理系统中启用此功能。RLS 涉及根据指定列中的值筛选对数据行的访问权限。您可以使用两种方法来筛选对数据的访问权限：
+ 将表中指定的数据列与当前 PostgreSQL 用户的值进行比较。该用户可以访问该列中等同于已登录的 PostgreSQL 用户的值。
+ 将表中指定的数据列与应用程序设置的运行时变量的值进行比较。在该会话期间，可以访问列中等同于运行时变量的值。

第二个选项是首选，因为第一个选项要求为每个租户创建一个新的 PostgreSQL 用户。相反，使用 PostgreSQL 的 SaaS 应用程序在查询 PostgreSQL 时应负责在运行时设置租户特定的上下文。这将产生强制执行 RLS 的效果。您也可以 table-by-table根据需要启用 RLS。作为最佳实践，应在所有包含租户数据的表上启用 RLS。

以下示例创建了两个表并启用 RLS。此示例将一列数据与运行时变量的值进行比较`app.current_tenant`。

```
-- Create a table for our tenants with indexes on the primary key and the tenant’s name
CREATE TABLE tenant (
    tenant_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    name VARCHAR(255) UNIQUE,
    status VARCHAR(64) CHECK (status IN ('active', 'suspended', 'disabled')),
    tier VARCHAR(64) CHECK (tier IN ('gold', 'silver', 'bronze'))
);
 
-- Create a table for users of a tenant
CREATE TABLE tenant_user (
    user_id UUID DEFAULT uuid_generate_v4() PRIMARY KEY,
    tenant_id UUID NOT NULL REFERENCES tenant (tenant_id) ON DELETE RESTRICT,
    email VARCHAR(255) NOT NULL UNIQUE,
    given_name VARCHAR(255) NOT NULL CHECK (given_name <> ''),
    family_name VARCHAR(255) NOT NULL CHECK (family_name <> '')
);
 
-- Turn on RLS
ALTER TABLE tenant ENABLE ROW LEVEL SECURITY;
 
-- Restrict read and write actions so tenants can only see their rows
-- Cast the UUID value in tenant_id to match the type current_setting
-- This policy implies a WITH CHECK that matches the USING clause
CREATE POLICY tenant_isolation_policy ON tenant
USING (tenant_id = current_setting('app.current_tenant')::UUID);
 
-- And do the same for the tenant users
ALTER TABLE tenant_user ENABLE ROW LEVEL SECURITY;
 
CREATE POLICY tenant_user_isolation_policy ON tenant_user
USING (tenant_id = current_setting('app.current_tenant')::UUID);
```

有关更多信息，请参阅博客文章[使用 PostgreSQL 行级安全进行多租户数据隔离](https://aws.amazon.com/blogs/database/multi-tenant-data-isolation-with-postgresql-row-level-security/)。S AWS aaS 工厂团队还有[一些示例 GitHub](https://github.com/aws-samples/aws-saas-factory-postgresql-rls)可以帮助实施 RLS。