PostgresSQLのRLS
PostgreSQLのRow Level Security
テーブルの行単位でアクセス制御を行う仕組み
https://www.postgresql.jp/docs/9.6/ddl-rowsecurity.html
GPT-4.icon
簡単に言えば、「誰がどの行を見たり変更したりできるか」を細かく制御できます。
RLS の基本
PostgreSQL では通常、PostgreSQLのroleに対してテーブル全体の SELECT, INSERT, UPDATE, DELETE 権限を与えます。
しかし、特定の条件を満たす行だけアクセスさせたい場合には不十分です。
RLS を使うと、例えば:
user_id = current_user_id の行だけ SELECT できる
自分が作成した投稿だけ UPDATE できる
といったきめ細やかな制御が可能になります。
🧩 仕組み
RLS は以下のように設定します。
① RLS を有効化
code:sql
ALTER TABLE your_table ENABLE ROW LEVEL SECURITY;
② ポリシーを定義
「Policy」は、(PostgresSQL全体ではなく)RLS固有の概念っぽいmrsekut.icon
code:sql
CREATE POLICY your_policy_name
ON your_table
FOR SELECT -- or INSERT / UPDATE / DELETE / ALL
TO public -- 適用するロール
USING (user_id = current_setting('app.current_user_id')::int);
この例では、user_id が現在のアプリユーザーと一致する行だけ SELECT を許可します。
※ current_setting('app.current_user_id') はアプリ側で SET app.current_user_id = '123'; のように設定する必要があります。
🛡️ デフォルトの制限
RLS を有効にすると、ポリシーがない限りそのテーブルにはアクセスできなくなります。つまり、安全側に倒れます。
✅ よくあるユースケース
マルチテナントアプリ:ユーザーごとに自分のデータしか見られないようにする
社内アプリ:部署によって見られるデータを分ける
監査ログ:DELETE を制限して変更不可にする
⚠️ 注意点
superuser や bypassrls 属性を持つロールには適用されません
current_user ではなく、アプリで SET するセッション変数を使うのが一般的です(current_setting())
💡補足:SET をどう使うか
アプリから RLS を使うには、セッション変数をセットするのが定石です。たとえば:
code:sql
SET app.current_user_id = '42';
この設定はそのセッション内でのみ有効なので、マルチユーザー環境でも安全です。