I'm having trouble understanding privileges in PostgreSQL.
E.g. I have a web application with the user webapiuser. This user is limited in the sense that it can only action the database through a function of some sort. That means no direct DB CRUD operations, only via functions created by the god postgres user and only functions within its own domain. I've done all sorts of reading with many tutorials point to adding SECURITY DEFINER to each function, but this allows the function to be executed by the function owner on behalf of the user which defeats the purpose in my understanding; I'm trying to lock down this sort of access after all.
I've already created a user with:
CREATE USER webapiuser WITH PASSWORD <password>;
And granted USAGE to all schemas:
GRANT USAGE ON SCHEMA schemaA TO webapiuser;
GRANT USAGE ON SCHEMA schemaB TO webapiuser;
GRANT USAGE ON SCHEMA poublic TO webapiuser;
I've tried adding:
GRANT EXECUTE ON FUNCTION schemaA.func_myfunction() TO webapiuser;
But then I'm hit with permission denied for view view_my_view. The function does select from this view so I guess the GRANT command is working. I get a similar error permission denied for table my_table if I execute a function that performs insert operations. How far down the privileges rabbit hole must I go to perform this seemingly simple task? And if I grant INSERT, UPDATE, DELETE privileges to this user on these tables directly then that defeats the purpose.
Shouldn't granting the user EXECUTE permissions on a function allow it to do anything within the scope of that function?
SECURITY DEFINERon the function (and have the owner of the function be a user with the necessary privileges on the used objects), or you need to grant those privileges to the user who is calling the function. There's no way around this.webapiuserprevent to do? What is your threat model, which things do you want to protect?webapiuserwould only ever perform CRUD operations via a function (if in fact that function specifies it). If connected to the database via some sort of access layer, no direct/dynamic SQL should be able to be executed by this user. Is this a misunderstanding of mine? What if I want all DB objects (tables, views, functions) to be created bypostgresand only want some users to interact with some of them via functions. Also,webapiusershould never be able to ALTER, DROP, ADD DB objects (tables, views and functions).webapiusershould never be able to ALTER, DROP, ADD DB objects" - those are DDL statements, which have their separate privileges anyway. The user won't gain those when you only grant CRUD.