db_pre_request issues in private schema #3023
-
I am trying to use db_pre_request to check user permissions on each request. It works like a charm when I put the function in the public schema like so: create or replace function public.check_permissions()
returns void
as $$
with user_permissions as (
select jsonb_build_object('permissions',jsonb_object_agg (permission, scope)) as data
from access_control.get_permissions()
)
select set_config('request.claims'::text, (select data::text from user_permissions), false );
$$ language sql security definer;
alter role authenticator set pgrst.db_pre_request TO 'check_permissions'; The problem is this function is now exposed in the public API. So, I want to move it to a private schema. Based on docs I did the following -- create a dedicated schema, hidden from the API
create schema "postgrest";
-- grant usage on this schema to the authenticator
grant usage on schema "postgrest" to "authenticator";
select set_config('pgrst.db_extra_search_path','public,postgrest,extensions',true);
notify pgrst,'reload config';
create or replace function public.check_permissions()
returns void
as $$
with user_permissions as (
select jsonb_build_object('permissions',jsonb_object_agg (permission, scope)) as data
from access_control.get_permissions()
)
select set_config('request.claims'::text, (select data::text from user_permissions), false );
$$ language sql security definer;
alter role authenticator set pgrst.db_pre_request TO 'postgrest.check_permissions'; I now get a 403 forbidden error on every request. I've tried
Anyone successfully done this before? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
I think there's a mistake in the new pre-request function declaration? ...
notify pgrst,'reload config';
-- it should be postgrest.check_permissions()
create or replace function public.check_permissions()
returns void
as $$
... But still, the Pre Request function is executed after the role is impersonated. So you'll need to grant usage on the schema to that user (the one in the JWT "role" key), e.g. if the role is grant usage on schema postgrest to web_user; It works in the public schema because every user has that privilege by default. I'm also wondering, does the function work as expected? I have that doubt because the pre request is done after the authentication. And what PostgREST and PostgreSQL versions are you using? |
Beta Was this translation helpful? Give feedback.
I figured out how to get this to work. Though I'm not exactly clear why. I think it has something to do with how
authenticator
switches intoanon
andauthenticated
roles (or whatever web_user and anon roles you've setup. These are the target roles in supabase)In order to have the db_request_function in a private schema, you must grant the following: