🐥

Row Level Security(行レベルセキュリティ)

2024/10/03に公開

はじめに

このページではPostgreSQLにおけるRow Level Security(行レベルセキュリティ)について記述します。

Row Level Security(RLS)とは

PostgreSQLのRow Level Security(RLS)は、テーブルの行に対してセキュリティポリシーを定義する機能です。この機能により、ユーザーやロールごとにどの行にアクセスできるかを細かく制御することができます。特定の条件に基づいて、クエリが取得できる行を制限することが可能です。

RLSの使用例

たとえば、複数の部門がデータベースの同じテーブルを共有している場合、各部門のユーザーは自分の部門に関連する行だけにアクセスできるようにする、といった制限が可能です。

Row Level Securityを有効にする方法

RLSを有効にするには、まずテーブルに対して行レベルセキュリティを有効にする必要があります。以下のコマンドでRLSを有効にできます。

ALTER TABLE テーブル名 ENABLE ROW LEVEL SECURITY;

たとえば、employees というテーブルでRLSを有効にする場合、以下のコマンドを実行します。

ALTER TABLE employees ENABLE ROW LEVEL SECURITY;

ポリシーの作成

次に、行に対するアクセスポリシーを定義します。ポリシーは、CREATE POLICY コマンドを使用して作成します。

CREATE POLICY policy_name ON テーブル名
    USING (条件式);

たとえば、特定の部門に所属する従業員のみが自分のデータにアクセスできるポリシーを作成する場合、以下のように定義します。

CREATE POLICY employee_policy ON employees
    USING (department_id = current_setting('myapp.current_department'));

このポリシーは、current_setting('myapp.current_department') の値が department_id 列と一致する行だけを返します。

RLSの動作を確認する

ポリシーを作成した後、RLSが正しく動作しているかを確認するためには、対象のテーブルに対してクエリを実行してみます。例えば、先ほどのポリシーに基づいて、current_setting('myapp.current_department') が「1」の場合、次のクエリは部門1の従業員データのみを返します。

SET myapp.current_department = '1';
SELECT * FROM employees;

RLSを強制する

デフォルトでは、スーパーユーザーやテーブルの所有者にはRLSの制限が適用されません。すべてのユーザーに対してRLSを強制するには、以下のコマンドを使用して強制ポリシーを有効化します。

ALTER TABLE テーブル名 FORCE ROW LEVEL SECURITY;

これにより、スーパーユーザーや所有者もポリシーに従うようになります。

パフォーマンスへの影響

RLSは非常に強力な機能ですが、パフォーマンスに影響を与える可能性があります。行レベルでのフィルタリングが行われるため、クエリの実行速度が遅くなる場合があります。大量のデータに対して複雑なポリシーを適用する場合は、クエリの最適化やインデックスの作成を検討する必要があります。

ポリシーとアクセス権限の違い

RLSはポリシーベースの行フィルタリングを提供しますが、アクセス権限とは異なります。アクセス権限は、テーブル全体に対しての読み取りや書き込みの権限を管理するものであり、RLSはその権限を持つユーザーに対しても行単位でアクセスを制限します。したがって、RLSとアクセス権限を併用することで、より細かいアクセス制御が可能となります。

バージョン情報

RLSはPostgreSQL 9.5以降でサポートされています。RLSを利用する際は、データベースのバージョンを確認してください。

まとめ

PostgreSQLのRow Level Security(RLS)は、行レベルでのアクセス制御を可能にする強力な機能です。テーブルに対してRLSを有効化し、ポリシーを定義することで、ユーザーごとにアクセス可能なデータを制限できます。ポリシー設計時にはパフォーマンスにも注意し、適切なインデックスの利用を検討することが重要です。

Discussion