0Pricing
SQL Academy · レッスン

行レベルセキュリティポリシー

ユーザーごとに行を自動でフィルタリングします。

「行レベルセキュリティポリシー」はCoddyKit上の無料SQL Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはSQL Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 SQL Academyコースには全4レッスンが含まれています。

行レベルセキュリティとは

行レベルセキュリティ(RLS)は、特定のデータベースユーザーまたはロールがテーブルのどの行を参照・変更できるかを制御できるPostgreSQLの機能です。すべてのクエリで行をフィルタリングする代わりに、ポリシーを一度定義すれば、PostgreSQLがすべてのSELECT、INSERT、UPDATE、DELETEに対して自動的に適用します。

特定のクエリではなく、テーブル自体に付加された目に見えないWHERE句だと考えると分かりやすいでしょう。

テーブルでのRLSの有効化

RLSはデフォルトでは無効です。各テーブルでALTER TABLE ... ENABLE ROW LEVEL SECURITYを使用して、明示的に有効化する必要があります。有効化すると、少なくとも1つのポリシーを作成するまで、テーブル所有者ではないロールには行が1件も表示されません。

-- Create a sample table
CREATE TABLE orders (
  id        SERIAL PRIMARY KEY,
  owner     TEXT NOT NULL,
  amount    NUMERIC(10,2)
);

-- Enable RLS
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

最初のポリシーの作成

ポリシーはCREATE POLICYで作成します。ポリシー名と対象テーブルを指定し、USING式を記述します。USING句は各行に対して評価されるBoolean式で、式の結果がTRUEになる行だけがユーザーに表示されます。

-- Allow each user to see only their own orders
CREATE POLICY orders_owner_policy
  ON orders
  FOR SELECT
  USING (owner = current_user);

USING 句と WITH CHECK 句

ポリシーには、異なる目的を持つ2つのフィルター句があります。

  • USING — 読み取り操作(SELECT、UPDATE、DELETE)で行をフィルタリングします。USING が TRUE を返す場合にのみ、その行が表示されます。
  • WITH CHECK — 書き込み操作(INSERT、UPDATE)で行を検証します。WITH CHECK が TRUE を返す場合にのみ、書き込みが許可されます。省略した場合は、書き込みのチェックにも USING が再利用されます。
-- Allow users to select and insert only their own rows
CREATE POLICY orders_isolation
  ON orders
  FOR ALL
  USING       (owner = current_user)
  WITH CHECK  (owner = current_user);

ポリシーの適用範囲: FOR SELECT、INSERT、UPDATE、DELETE

1つのポリシーで、すべてのコマンド(FOR ALL)または特定のコマンドを対象にできます。コマンドごとにポリシーを分けると、きめ細かな制御が可能になります。たとえば、すべてのユーザーにすべての行の読み取りを許可しつつ、自分の行だけを変更できるようにできます。

-- Everyone can read all orders
CREATE POLICY read_all_orders
  ON orders
  FOR SELECT
  USING (true);

-- But each user can only update their own orders
CREATE POLICY update_own_orders
  ON orders
  FOR UPDATE
  USING       (owner = current_user)
  WITH CHECK  (owner = current_user);

session_user と current_user の使用

PostgreSQL には、ポリシー式の中で現在のユーザーを識別する組み込み関数が用意されています。

  • current_user — 現在有効な権限を持つロールです(SET ROLE の後に変わる場合があります)。
  • session_user — 接続を開始したロールです(セッション中は変わりません)。

多くの RLS ポリシーでは、ロール切り替え後の実効ロールを反映する current_user を使用します。

-- Inspect the current identity inside a query
SELECT current_user, session_user;

特定のロールへの RLS の適用

デフォルトでは、ポリシーは PUBLIC(すべてのロール)に適用されます。TO 句を使用すると、特定のロールに制限できます。通常のユーザー向けのポリシーと、管理者ロール向けの別のポリシーを用意したい場合に便利です。

-- Policy only for the 'app_user' role
CREATE POLICY app_user_policy
  ON orders
  FOR SELECT
  TO app_user
  USING (owner = current_user);

-- Separate permissive policy for 'admin' role
CREATE POLICY admin_full_access
  ON orders
  FOR ALL
  TO admin
  USING (true)
  WITH CHECK (true);

PERMISSIVE ポリシーと RESTRICTIVE ポリシー

同じテーブルに複数のポリシーを設定した場合、ポリシーは次の2通りの方法で作用します。

  • PERMISSIVE(デフォルト) — すべての PERMISSIVE ポリシーを OR で結合します。いずれかの PERMISSIVE ポリシーが許可すれば、その行にアクセスできます。
  • RESTRICTIVE — RESTRICTIVE ポリシーを、PERMISSIVE ポリシーの結果に AND で適用します。RESTRICTIVE ポリシーを通過し、かつ少なくとも1つの PERMISSIVE ポリシーが許可した場合にのみ、その行にアクセスできます。
-- Restrictive policy: block access to archived orders for everyone
CREATE POLICY no_archived_rows
  ON orders
  AS RESTRICTIVE
  FOR SELECT
  USING (amount > 0);

RLS のバイパス: BYPASSRLS とテーブル所有者

テーブル所有者とスーパーユーザーは、デフォルトで RLS をバイパスし、常にすべての行を参照できます。スーパーユーザーにせずに無制限のアクセスを必要とするロールには、BYPASSRLS 属性を付与できます。反対に、FORCE ROW LEVEL SECURITY を使用すると、所有者にも RLS の適用を強制できます。

-- Force the table owner to also obey RLS policies
ALTER TABLE orders FORCE ROW LEVEL SECURITY;

-- Grant BYPASSRLS to a trusted service account
ALTER ROLE service_account BYPASSRLS;

ポリシーの変更と削除

既存のポリシーは ALTER POLICY で変更でき、DROP POLICY で完全に削除できます。RLS を有効にしたまますべてのポリシーを削除すると、所有者以外のロールはどの行にもアクセスできなくなります。RLS を完全に解除するには、ALTER TABLE で無効にします。

-- Rename a policy
ALTER POLICY orders_owner_policy ON orders
  RENAME TO user_isolation_policy;

-- Update the USING expression
ALTER POLICY user_isolation_policy ON orders
  USING (owner = current_user AND amount >= 0);

-- Remove a policy
DROP POLICY admin_full_access ON orders;

-- Disable RLS entirely on the table
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;

実例: マルチテナントデータの分離

マルチテナント SaaS アプリでよく使われる RLS パターンでは、すべてのテーブルに tenant_id 列を持たせ、セッションレベルの変数(set_config)を使って接続時にテナント識別子を渡します。その後、ポリシーで各行の tenant_id とその設定値を比較します。

-- Table with tenant isolation column
CREATE TABLE documents (
  id         SERIAL PRIMARY KEY,
  tenant_id  TEXT NOT NULL,
  title      TEXT
);

ALTER TABLE documents ENABLE ROW LEVEL SECURITY;

-- Policy reads the tenant from a session variable
CREATE POLICY tenant_isolation
  ON documents
  FOR ALL
  USING       (tenant_id = current_setting('app.tenant_id'))
  WITH CHECK  (tenant_id = current_setting('app.tenant_id'));

-- Application sets the variable before running queries
SELECT set_config('app.tenant_id', 'tenant_42', true);

-- Now only tenant_42 documents are visible
SELECT * FROM documents;

理解度チェック

PostgreSQL の行レベルセキュリティポリシーについての理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、行レベルセキュリティによって、データベースレベルでポリシーに基づく行のフィルタリングを自動的に行う方法を学びました。

  • RLS の有効化 — ALTER TABLE ... ENABLE ROW LEVEL SECURITY を使用してテーブルで RLS を有効にします。
  • CREATE POLICY で USING 句を使用して読み取り可能な行をフィルタリングし、WITH CHECK 句を使用して書き込まれる行を検証します。
  • TO 句を使用して、ポリシーの対象を特定のコマンド(SELECT、INSERT、UPDATE、DELETE、ALL)や特定のロールに限定します。
  • PERMISSIVE(OR ロジック)と RESTRICTIVE(AND ロジック)のポリシーを組み合わせて、多層的なアクセス制御を実現します。
  • テーブル所有者とスーパーユーザーはデフォルトで RLS をバイパスします。これを上書きするには FORCE ROW LEVEL SECURITY を使用します。
  • current_setting() を使用するマルチテナントパターンは、RLS の強力な実用例です。

RLS は、アプリケーションのすべてのクエリに WHERE 句を分散させることなく、データ分離を適切かつ一貫して適用する標準的な方法です。

よくある質問

「行レベルセキュリティポリシー」レッスンは無料ですか?

はい。「行レベルセキュリティポリシー」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、SQL Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 SQL Academyコースには全4レッスンが含まれています。

「行レベルセキュリティポリシー」で何を学びますか?

ユーザーごとに行を自動でフィルタリングします。 ブラウザで直接実行するハンズオンコードでSQL Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

SQL Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのSQL Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「行レベルセキュリティポリシー」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このSQL Academyレッスンでコードを書いて実行できますか?

はい。すべてのSQL Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ロールと権限
  2. 行レベルセキュリティポリシー
  3. 列レベルの権限
  4. アクセスを監査する
← SQL Academyに戻る