SCALE — Build Lab
開発パターン · SQL MIGRATION

Supabase RLS(Row Level Security)設計

CATEGORY開発パターン TYPESQL Migration EFFORT90〜240分 DIFFICULTY
PRIMARY CODE
tsx · scale-crm:SUPABASE_RLS_MIGRATION.sql
-- =====================================================================
-- SCALE CRM — Supabase RLS 適正化マイグレーション
-- =====================================================================
-- 実行方法:
--   1. Supabase Dashboard → SQL Editor を開く
--   2. このファイル全体をコピペ
--   3. Run ボタンで実行
--
-- 背景:
--   現在の app_data テーブルは「Allow all access」ポリシーで、
--   publishable キーを持つ誰でも全データを読み書きできる状態。
--   社内ツールとはいえ、URLが漏れれば全顧客データが流出する。
--
-- 対応方針:
--   A) まず「ドメイン制限」だけでも強く効く(Cloudflare Access 等で保護)
--   B) 本格的には「認証済みユーザーのみアクセス可」にする(Supabase Auth導入)
--   C) 緊急避難的に IP 制限(Supabase のネットワーク制限機能)
--
-- 本マイグレーションは B に向けた第一歩として、
--   - 匿名ユーザーの書き込みを禁止
--   - 読み取りは匿名でも可能(既存動作を壊さないため)
--   - 認証実装後に READ も制限するためのコメント付き
-- を提供します。
-- =====================================================================

-- 1. 既存の「Allow all」ポリシーを削除
DROP POLICY IF EXISTS "Allow all access" ON app_data;
DROP POLICY IF EXISTS "Enable read access for all users" ON app_data;
DROP POLICY IF EXISTS "Enable insert for all users" ON app_data;
DROP POLICY IF EXISTS "Enable update for all users" ON app_data;
DROP POLICY IF EXISTS "Enable delete for all users" ON app_data;

-- 2. RLS を明示的に ON
ALTER TABLE app_data ENABLE ROW LEVEL SECURITY;

-- 3. 読み取りポリシー: 認証済みユーザーのみ
--    ※ 現状のフロントは anon key を使っているため、まず authenticated にだけ許可すると既存動作が壊れる
--    ※ 段階移行のため、anon にも一旦許可しておく(後で下記コメント部分を入れ替え)
CREATE POLICY "app_data_read_anon_temporary"
  ON app_data FOR SELECT
  TO anon
  USING (true);

CREATE POLICY "app_data_read_authenticated"
  ON app_data FOR SELECT
  TO authenticated
  USING (true);

-- 4. 書き込みポリシー: 認証済みユーザーのみ(anon は書き込み不可)
--    これを有効にすると、現行フロントが動作しなくなる可能性がある。
--    段階移行のため、いったん anon 書き込みも許可する版も用意。
--    【本番移行時に入れ替える】
--
-- ■ 推奨(Supabase Auth導入後):
CREATE POLICY "app_data_write_authenticated"
  ON app_data FOR ALL
  TO authenticated
  USING (true)
  WITH CHECK (true);

-- ■ 暫定(現行フロント互換、書き込みも anon 許可):
--    Supabase Auth を導入するまではこちらが必要
CREATE POLICY "app_data_write_anon_temporary"
  ON app_data FOR ALL
  TO anon
  USING (true)
  WITH CHECK (true);


-- =====================================================================
-- 次のステップ(Supabase Auth導入時)
-- =====================================================================
-- 1. Supabase Dashboard → Authentication → Providers で Email/Password 有効化
-- 2. 既存のメンバー(大串・細川 等)を Auth.users に登録
-- 3. フロント側を supabase.auth.signInWithPassword に切り替え
-- 4. 上記「anon_temporary」ポリシーを DROP する
--
-- DROP POLICY "app_data_read_anon_temporary" ON app_data;
-- DROP POLICY "app_data_write_anon_temporary" ON app_data;
--
-- 5. 必要であれば更に細かく「自分のorgのデータしか見えない」等の
--    マルチテナント対応ポリシーを追加


-- =====================================================================
-- 最小限の防御壁として「Cloudflare Access」を推奨
-- =====================================================================
-- RLS 完全対応までの緊急対策として、Cloudflare Access で
-- crm.scale-group.co.jp に Google SSO を掛ければ、
-- 部外者が URL を知ってもログインできず、実質的に保護できます。
--
-- 設定手順:
--   1. Cloudflare Zero Trust ダッシュボードを開く
--   2. Access → Applications → Add an application
--   3. Self-hosted → Application name: SCALE CRM
--      Application domain: crm.scale-group.co.jp
--   4. Policy: Allow → Emails ending in @scale-group.co.jp
--   5. 保存
--
-- これで部外者は Google ログインで弾かれ、内部ユーザーは透過的にアクセス可能。

前提条件
Tailwind CSS v4TypeScript 5
USE CASES
  • マルチテナント SaaS
  • ユーザー別データ分離

Supabase RLS(Row Level Security)設計

:LiTarget: 用途

Supabase の Row Level Security 設定例。マルチテナント・ユーザー別データ分離の実装。

:LiSparkle: 特徴

  • RLS ポリシー設定
  • auth.uid() 利用
  • テナント別分離
  • マイグレーション手順

:LiCode: 実コード(SCALE Base より自動抽出)

:LiInfo: scale-crm:SUPABASE_RLS_MIGRATION.sql の中身そのもの。コピペ即可。

-- =====================================================================
-- SCALE CRM — Supabase RLS 適正化マイグレーション
-- =====================================================================
-- 実行方法:
--   1. Supabase Dashboard → SQL Editor を開く
--   2. このファイル全体をコピペ
--   3. Run ボタンで実行
--
-- 背景:
--   現在の app_data テーブルは「Allow all access」ポリシーで、
--   publishable キーを持つ誰でも全データを読み書きできる状態。
--   社内ツールとはいえ、URLが漏れれば全顧客データが流出する。
--
-- 対応方針:
--   A) まず「ドメイン制限」だけでも強く効く(Cloudflare Access 等で保護)
--   B) 本格的には「認証済みユーザーのみアクセス可」にする(Supabase Auth導入)
--   C) 緊急避難的に IP 制限(Supabase のネットワーク制限機能)
--
-- 本マイグレーションは B に向けた第一歩として、
--   - 匿名ユーザーの書き込みを禁止
--   - 読み取りは匿名でも可能(既存動作を壊さないため)
--   - 認証実装後に READ も制限するためのコメント付き
-- を提供します。
-- =====================================================================

-- 1. 既存の「Allow all」ポリシーを削除
DROP POLICY IF EXISTS "Allow all access" ON app_data;
DROP POLICY IF EXISTS "Enable read access for all users" ON app_data;
DROP POLICY IF EXISTS "Enable insert for all users" ON app_data;
DROP POLICY IF EXISTS "Enable update for all users" ON app_data;
DROP POLICY IF EXISTS "Enable delete for all users" ON app_data;

-- 2. RLS を明示的に ON
ALTER TABLE app_data ENABLE ROW LEVEL SECURITY;

-- 3. 読み取りポリシー: 認証済みユーザーのみ
--    ※ 現状のフロントは anon key を使っているため、まず authenticated にだけ許可すると既存動作が壊れる
--    ※ 段階移行のため、anon にも一旦許可しておく(後で下記コメント部分を入れ替え)
CREATE POLICY "app_data_read_anon_temporary"
  ON app_data FOR SELECT
  TO anon
  USING (true);

CREATE POLICY "app_data_read_authenticated"
  ON app_data FOR SELECT
  TO authenticated
  USING (true);

-- 4. 書き込みポリシー: 認証済みユーザーのみ(anon は書き込み不可)
--    これを有効にすると、現行フロントが動作しなくなる可能性がある。
--    段階移行のため、いったん anon 書き込みも許可する版も用意。
--    【本番移行時に入れ替える】
--
-- ■ 推奨(Supabase Auth導入後):
CREATE POLICY "app_data_write_authenticated"
  ON app_data FOR ALL
  TO authenticated
  USING (true)
  WITH CHECK (true);

-- ■ 暫定(現行フロント互換、書き込みも anon 許可):
--    Supabase Auth を導入するまではこちらが必要
CREATE POLICY "app_data_write_anon_temporary"
  ON app_data FOR ALL
  TO anon
  USING (true)
  WITH CHECK (true);


-- =====================================================================
-- 次のステップ(Supabase Auth導入時)
-- =====================================================================
-- 1. Supabase Dashboard → Authentication → Providers で Email/Password 有効化
-- 2. 既存のメンバー(大串・細川 等)を Auth.users に登録
-- 3. フロント側を supabase.auth.signInWithPassword に切り替え
-- 4. 上記「anon_temporary」ポリシーを DROP する
--
-- DROP POLICY "app_data_read_anon_temporary" ON app_data;
-- DROP POLICY "app_data_write_anon_temporary" ON app_data;
--
-- 5. 必要であれば更に細かく「自分のorgのデータしか見えない」等の
--    マルチテナント対応ポリシーを追加


-- =====================================================================
-- 最小限の防御壁として「Cloudflare Access」を推奨
-- =====================================================================
-- RLS 完全対応までの緊急対策として、Cloudflare Access で
-- crm.scale-group.co.jp に Google SSO を掛ければ、
-- 部外者が URL を知ってもログインできず、実質的に保護できます。
--
-- 設定手順:
--   1. Cloudflare Zero Trust ダッシュボードを開く
--   2. Access → Applications → Add an application
--   3. Self-hosted → Application name: SCALE CRM
--      Application domain: crm.scale-group.co.jp
--   4. Policy: Allow → Emails ending in @scale-group.co.jp
--   5. 保存
--
-- これで部外者は Google ログインで弾かれ、内部ユーザーは透過的にアクセス可能。

:LiFolder: ソースファイルのパス

/Users/oogushiyuuki/株式会社SCALE/scale-lead/SUPABASE_RLS_MIGRATION.sql

:LiHandPointer: 使い方

対象プロジェクトに該当ファイルをコピーして、props を流し込むだけ。

:LiAlertCircle: 注意事項

  • 依存パッケージを忘れず追加