pg_graphql icon indicating copy to clipboard operation
pg_graphql copied to clipboard

Is there a { returning: "minimal" } option for mutations on tables with RLS with only insert allowed

Open ajlai24 opened this issue 3 years ago • 1 comments

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?

ajlai24 avatar Aug 12 '22 22:08 ajlai24

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

olirice avatar Sep 21 '22 14:09 olirice