はじめに
データベースの権限管理で頭を悩ませていませんか?
Supabaseの強みは、PostgreSQLのRow Level Security (RLS) を活用して行単位のアクセス制御ができる点にあります。
今回は実際のプロジェクトで得た知見をもとに、Supabaseを使って、アプリケーション専用の権限テーブルを設計し、RLSと組み合わせる多層防御を行う方法を紹介します。
「RLSって何?」という方から、「より堅牢なセキュリティを目指したい」というベテランの方まで、きっと新しい発見があるはずです。
1. RLSとアプリ権限テーブルはなぜ両立させるのか
-
RLS (Row Level Security)
DBレベルで「誰がどの行を読み書きできるか」を制御。
たとえば自分の投稿のみ閲覧・編集できるようにするなど、1行単位の細かいルール設定が可能です。 -
アプリケーション権限テーブル
アプリのロール・ポリシー管理用に独自設計したテーブル群(ER図参照)から、ユーザーがどの機能・リソースにアクセスできるかを判断します。- DBのGRANT機能を使うわけではなく、ユーザーロールやポリシーテーブルを参照しつつ、アプリが「この操作はOK」と判断してAPIを通すイメージです。
両者を組み合わせるメリットは、万が一アプリケーション側が誤って不適切な操作を許可してしまっても、最後の砦としてRLSが行レベルでブロックしてくれるところにあります。
2. anonキーとservice_roleキーの使い分け
anonキー
-
公開用キー
フロントエンドからのリクエストで使用し、RLS適用下でアクセスします。 -
アプリ権限テーブルを組み合わせた利用例
- ユーザーがログインすると、アプリ側が権限テーブルから「このユーザーは読込/書込権限があるか?」を判定
- 許可された操作のみSupabaseのAPIに投げる
- SupabaseはRLSで行単位のアクセス制限を実施
service_roleキー
-
特権キー
RLSをバイパスでき、すべての行に対して操作可能。 -
利用シーン
- CMSや管理画面など、管理者が全データを確認・操作する必要がある場合
- バッチ処理やバックエンドでの一括更新・集計など
この2種類のキーを使い分けることで、一般ユーザーにはRLSで厳密に行制限をかけつつ、管理者はRLSを気にせずすべての行にアクセスできるようになります。
詳細は以下の記事をご確認ください。
3. アプリ権限テーブル設計例
下図は、ロールやポリシーを組み合わせてアプリ側で「ユーザーがどんな操作をできるか」を管理するためのER図です。
設計のポイント
-
ユーザーが所属するロール
-
roles
テーブルに施設ごとのロールを登録 -
user_roles
でユーザーとロールを紐づけ
-
-
権限の定義方法
-
policies
テーブルに機能ごとのポリシーを管理(たとえば「在庫閲覧」「在庫追加」「在庫削除」など) -
role_policies
でロールとポリシーを紐づけし、「このロールはどのポリシーを実行できるか」定義
-
-
アプリ起動時またはログイン時に判定
- ユーザーがAPIを叩く前に、ロールやポリシーを参照して「この操作は許可されるか」をチェック
- アプリ側の論理で「許可された操作だけ」をSupabaseに渡す
4. 多層防御の流れ
-
ログイン
- anonキーを使い、RLS下でDBに接続
- 同時にアプリ側で
user_roles
/user_policies
などを読み込み、「どの操作を実行可能か」を把握
-
ユーザーの操作
- ユーザーが在庫追加・レコード編集などを要求
- アプリがまず「ロール・ポリシーを満たしているか?」を確認
- 権限がある操作だけSupabaseのエンドポイントへリクエスト
-
RLSの再チェック
- Supabase側で、RLSが「この行はユーザーに返していいか?」を最終判定
- 条件に合わない行は自動的にブロックされる
こうすることで、アプリレベルのロール・ポリシー管理+RLSによる行制限の二重構造が実現します。
まとめ
-
アプリケーション側での権限チェック(ER図のテーブル設計)
- ユーザーがどんな操作を許可されているかをロール・ポリシーで一元管理
- アプリで「操作OK/NG」を判断し、不要なAPIコールを避ける
-
Row Level Security (RLS) による行単位制御
- 万が一アプリが誤ってリクエストしても、行レベルでDBがしっかりとアクセスを制限
-
anonキー & service_roleキーの活用
- 一般ユーザーはRLS下のanonキーで安全に操作
- 管理者やCMSはservice_roleキーでRLSをバイパスし、すべての行を操作
このように、アプリケーション側の権限テーブルによるチェックとRLSを併用することで、多層的にシステムを守ることができます。
誤設定やアプリのバグがあっても、DBレベルで最終防御ラインを敷いておけば安心です。
Supabaseの柔軟な機能をフル活用して、セキュアで拡張性のあるアプリケーションを構築してみてください。