はるさめ.dev

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 ロールにしか権限が割り振られていないことがわかります。

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

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

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;

コメント