pg_graphql
pg_graphql copied to clipboard
Is there a { returning: "minimal" } option for mutations on tables with RLS with only insert allowed
Summary
I have a basic table with an email column where I enabled RLS to only allow INSERT for anon. This is for a use case like a waitlist where the user can add their email to a waitlist but shouldn't be able to query or SELECT any of the waitlist.
I noticed here that there's a { returning: "minimal" } option when doing an insert using supabase-js but I didn't see anywhere where that option could be set for a graphql mutation. As a result, I get the error: new row violates row-level security policy for table
Is there a way to do this for graphql mutations or is there a recommended alternative method of doing something like this?
sorry for the huge delay getting back to you! that isn't normal, my notifications were off on accident
Okay (for internal reference), here's a quick repro case for the error condition
create schema ex;
-- Create log table for output messages
create table ex.logg (
id serial primary key,
logg text not null
);
create role garb;
grant usage on schema ex to garb;
grant usage on all sequences in schema ex to garb;
grant insert on ex.logg to garb;
revoke select on ex.logg from garb;
select pg_catalog.has_table_privilege('garb', 'ex.logg'::regclass, 'SELECT'); -- false
select pg_catalog.has_table_privilege('garb', 'ex.logg'::regclass, 'INSERT'); -- true
begin;
-- Use the garb role
set local role = garb;
insert into ex.logg(logg) values ('a'); -- success
insert into ex.logg(logg) values ('b') returning id; -- failure
-- ERROR: permission denied for table logg
-- SQL state: 42501
rollback;
The rationale for using return * be default (ref) was because extending types with functions (doc) takes a table's record/row type, which requires select privilege on all columns.
I think you're correct that the better choice would be to return only the columns that the user has privilege for and extending with functions should be disabled when pg_catalog.has_table_privilege(role, table, 'SELECT') is false.
marked to fix