はるさめ.dev

Prisma と Supabase の REST API で permission denied

投稿日:Sat Jun 15 2024 12:32:30 GMT+0000 (Coordinated Universal Time)

背景

  1. 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 をする前とした後で新しくテーブルを作成したときの権限設定を一覧したときの画像。

通常新しくテーブルを作成したときに割り振られる権限一覧

prisma db reset する前は anon, authenticated にも権限が割り振られていることが見て取れる。

prisma db reset をした後に新しくテーブルを作成したときに割り振られる権限一覧

権限が postgres にしか割り振られていない。

なお、テーブルの権限を一覧する際は以下のクエリを使用している。

SELECT *
FROM information_schema.role_table_grants
WHERE table_schema='public' and table_name='test';

解決

1. Supabase の DB をリセットする

ローカル環境で supabase cli で環境を立ち上げている場合限定。
ターミナルから以下のコマンドを実行して DB をリセット。
$ pnpm dlx supabase stop --no-backup
$ pnpm dlx supabase start

その後、prisma でスキーマをデプロイする。

$ pnpm prisma migrate deploy

データがなくなってしまっても問題ない場合。

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;