

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 資料列層級安全建議
<a name="rls"></a>

資料列層級安全性 (RLS) 是使用 PostgreSQL 在混合模型中維護租戶資料隔離的必要條件。RLS 會在資料庫層級集中強制執行隔離政策，並免除維護與軟體開發人員隔離的負擔。實作 RLS 的最常見方法是在 PostgreSQL 資料庫MS 中啟用此功能。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/)。在 GitHub 中， AWS SaaS 工廠團隊也有一些範例，可協助實作 RLS。 [ GitHub](https://github.com/aws-samples/aws-saas-factory-postgresql-rls) 