Prisma と Supabase の REST API で permission denied
に公開背景
Supabase への DB アクセスは Prisma を利用していて、テーブルの管理も Prisma から行っている。
RLS の挙動を確かめるために、 REST API(Supabase Client)経由でテーブルを select したところ、RLS が無効になっているにも関わらず、以下のようなエラーが返ってきました。
{
"code": "42501",
"details": null,
"hint": null,
"message": "permission denied for schema public"
}
※ 別の環境では permission denied for table XXX というエラーメッセージのときもありました。
本来 RLS が無効になっていると REST API から自由にアクセスできるはずです。
また、念の為 RLS を有効にして以下のような任意のロールで SELECT を許可するポリシーを設定しても同じエラーが発生しました。
CREATE POLICY "Enable read access for all users”
ON "public".”Customer" AS PERMISSIVE
FOR SELECT
TO public
USING ( true);
原因
データベースをリセットする際に prisma migrate reset
をしたため、 public
スキーマが再作成されて、テーブル作成時に自動的にロールに権限を割り振る設定が削除されてしまうことが原因のようです。
そのため、本来新しくテーブルを作成したときに割り振られるはずの権限が anon ロールと authenticated ロールに割り振られず、REST API からのアクセス permission error になっていました。
(REST API でアクセスした場合は anon ロール、認証済みの場合は authenticated ロールになる)
次の画像は prisma migrate reset
をする前の画像で、anon や authenticated ロールに権限が割り振られていることがわかります。

次の画像は prisma migrate reset
した後の画像で、postgres ロールにしか権限が割り振られていないことがわかります。

なお、テーブルの権限を一覧する際は以下のクエリを使用しています。
SELECT *
FROM information_schema.role_table_grants
WHERE table_schema='public' AND table_name='test';
解決方法
1. 方法1:Supabase の DB をリセットする
ローカル環境で supabase cli で環境を立ち上げている場合で、データが消えてしまってもいい場合限定です。
ターミナルから以下のコマンドを実行して DB をリセット。
$ pnpm dlx supabase stop --no-backup
$ pnpm dlx supabase start
その後、prisma でスキーマをデプロイ。
pnpm prisma migrate deploy
2. 方法2:権限を手動で割り振る
データが消えない&リモート環境でも対応可能。
以下のクエリを実行。
Prisma - Supabase の Troubleshooting の Missing grants の項から引用。
grant usage on schema public to postgres, anon, authenticated, service_role;
grant all privileges on all tables in schema public to postgres, anon, authenticated, service_role;
grant all privileges on all functions in schema public to postgres, anon, authenticated, service_role;
grant all privileges on all sequences in schema public to postgres, anon, authenticated, service_role;
alter default privileges in schema public grant all on tables to postgres, anon, authenticated, service_role;
alter default privileges in schema public grant all on functions to postgres, anon, authenticated, service_role;
alter default privileges in schema public grant all on sequences to postgres, anon, authenticated, service_role;