Grant an automatic select to a all tables / PostgreSQL - sql

I have a production database, where the user can create a set of tables that inherits a master table X. The matter is when i want to apply an automatic grant for all the tables;
Naturally with this command : GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only ; this will only be applied to tables that have already been created.
The aim, is to applied the command for all the newest tables.
NB : I already tried to make a trigger on tables pg_class,
pg_namespace but it's impossible and it's the same for the pg_tables
view;

You can set the default grants for newly created objects with the ALTER DEFAULT PRIVILEGES command, e.g.:
ALTER DEFAULT PRIVILEGES
FOR USER creator_role IN SCHEMA public
GRANT SELECT ON TABLES TO read_only;
As an aside, while you can't install triggers on the system catalogs, you can achieve the same thing (in Postgres 9.3+) with event triggers, which fire on any CREATE/DROP/ALTER statement.

Related

Create DML, DDL, DQL user in PostgreSQL

I need to create 3 users with different DML, DDL, DQL on newly created clean Database in PostgreSQL.
DML should have SELECT, UPDATE, DELETE
DDL should have CREATE, DROP, ALTER, TRUNCATE, INSERT
DQL should have SELECT
all of this in standard scheme public.
Important is that user inherit right on newly created tables by DDL user.
users ref: https://www.geeksforgeeks.org/sql-ddl-dql-dml-dcl-tcl-commands/
I did some coding but I'm pretty new in PostgreSQL and it didn't work :(
The main problem was that I cannot perform GRANT or REVOKE on CREATE, DROP, ALTER, TRUNCATE :(
Can someone help please?
Maybe you have something similar already prepared?
The setup you want, can be done to some extent. However these privileges are controlled on schema level, not on database level.
Assuming you have a schema app_schema for which this should be defined, you can do the following:
First create the users:
create user ddl with password '***';
create user dml with password '***';
create user dql with password '***';
Then create the schema:
create schema app_schema;
Then allow the ddl user to create objects:
grant create,usage on schema app_schema to ddl;
Then change the default privileges on the schema, so that every table (or view, or sequence ...) created by the ddl user is accessible by the dml and dql users:
alter default privileges
for role ddl
grant select,update,delete on tables
to dml;
alter default privileges
for role ddl
grant select on tables
to dql;
This will affect all future tables created in the schema by the user ddl.
The owner of the tables automatically has the privileges to INSERT,UPDATE,DELETE or TRUNCATE the tables.
I have never tried this, but it seems possible to revoke the UPDATE and SELECT privileges:
alter default privileges
for role ddl
in schema app_schema
revoke update,select,delete on tables
from ddl;
If there are already tables in the schema, you need to grant the desired privileges for them:
grant select,insert,update,delete on all tables
in schema app_schema
to dml;
grant select on all tables
in schema app_schema
to dql;

How to set SELECT default privileges in PostgreSQL schema for new tables? [duplicate]

Currently I am using this to grant permissions:
grant select on all tables in schema public to <user_name>;
alter default privileges in schema public grant select on tables to <user_name>;
According to the documentation, the second statement should have resolved the problem. It does not however auto grant permissions to user_name when a new table is added to the public schema.
I am using this user (user_name) to copy data over to another database.
Found the answer. It is in this line in the ALTER DEFAULT PRIVILEGES documentation.
You can change default privileges only for objects that will be created by yourself or by roles that you are a member of.
I was using alter default privileges from a different user than the one creating the tables.
Make sure to set the role to the user creating the table before the alter default privilege statement:
SET ROLE <user_that_creates_new_tables>;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO <user_name>;
To grant default privileges, you need to grant to the user you are creating the table with.
You are creating the tables as SA_user, but reading the tables as READ_user. Your code needs to look like:
ALTER DEFAULT PRIVILEGES
FOR USER SA_user
IN SCHEMA schema_name
GRANT SELECT ON TABLES TO READ_user;
So whenever the SA_user creates a table, it will grant select rights for the READ_user.
I was looking for same thing, I found other way to solve this. Based on postgresql documentation we can create event trigger, so when new table is created, grant query will execute automatically. So no matter who created new table, other user allowed to use it.
CREATE OR REPLACE FUNCTION auto_grant_func()
RETURNS event_trigger AS $$
BEGIN
grant all on all tables in schema public to <username>;
grant all on all sequences in schema public to <username>;
grant select on all tables in schema public to <username>;
grant select on all sequences in schema public to <username>;
END;
$$ LANGUAGE plpgsql;
CREATE EVENT TRIGGER auto_grant_trigger
ON ddl_command_end
WHEN TAG IN ('CREATE TABLE', 'CREATE TABLE AS')
EXECUTE PROCEDURE auto_grant_func();

Role permissions don't get assigned to table moved from public schema

I want to create new schemas and transfer the table in public schema to these schemas, but whenever I'm moving a table from the public schema to another schema, the user/role which has usage access on the new schema, as well as on its tables (including future tables), isn't able to access the newly moved table.
The table (in public schema):
CREATE TABLE atable(ID INT);
INSERT INTO atable VALUES(1);
INSERT INTO atable VALUES(2);
New user:
create user x_user with login password 'x_user';
New schema:
create schema dw;
Then I grant it all the access to the new schema and its tables:
GRANT USAGE ON SCHEMA dw TO x_user;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA dw to x_user;
GRANT SELECT ON ALL TABLES IN SCHEMA dw TO x_user;
For tables added to the schema in the future
ALTER DEFAULT PRIVILEGES IN SCHEMA dw GRANT SELECT ON TABLES TO x_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA dw GRANT USAGE ON SEQUENCES TO x_user;
Now I change the schema of the atable to dw:
ALTER TABLE atable SET SCHEMA dw;
Also, I create another table in the dw schema:
CREATE TABLE dw.btable(id int);
INSERT INTO dw.btable VALUES(3);
INSERT INTO dw.btable VALUES(4);
Now when I connect to the database, using the new user credentials, and run:
SELECT * FROM dw.atable;
I get: ERROR: permission denied for relation atable 1 statement failed.
Whereas if I run the same query for btable , which was created in the dw schema, it works.
SELECT * FROM dw.btable;
id
---
3
4
It also works when I move a table from one schema to another, but when I'm moving a table from the public schema to another schema, it is not working.
What am I doing wrong here?
GRANT ... ON ALL TABLES IN SCHEMA affects only the current contents of the schema.
ALTER DEFAULT PRIVILEGES IN SCHEMA affects tables created in the schema.
Neither of these have any effect when moving tables from one schema to another, and I'm not aware of anything which does.
It should be possible to do this by creating an event trigger which fires on any ALTER TABLE command and applies the appropriate GRANT. Unfortunately, while you can write these trigger functions in PL/pgSQL, I don't think it (currently) provides any way to find out what the actual command was; you'd need to either:
Write a C function to inspect the pg_ddl_command structure returned by pg_event_trigger_ddl_commands(), or
Blindly run a GRANT after every ALTER TABLE, regardless of whether or not it was a SET SCHEMA command.
A far simpler option - provided that it fits your use case - would be to write a move_table() function which combines the ALTER and GRANT commands.

postgres table privileges do not allow user to create/select view

I am managing a database that has a number of schemas. I am having some difficulty with setting privileges and would like to request some help.
I have the schema called schemaA and a group_role db_writer
I use the following sql:
GRANT USAGE ON SCHEMA schemaA TO db_writer;
GRANT UPDATE, INSERT, SELECT, DELETE ON ALL TABLES IN SCHEMA schemaA TO db_writer;
However, the db_writer is unable to create views. They are returned with a permission denied error. Also, when I create views, she is then unable to select them...and I have to set the priviliges again for that view.
It was my understanding the views were treated as tables with respect to privileges...and if one is granted certain permissions to all tables in a schema this would apply to views also.
What am I missing? Any advice appreciated.
The problem is USAGE does not allow users to create objects within the database.
Try
GRANT USAGE, CREATE ON SCHEMA schemaA TO db_writer
Edit:
New objects will get default privileges, for the user to have those privileges for objects created in the future you can do it as:
ALTER DEFAULT PRIVILEGES IN SCHEMA schemaA GRANT UPDATE, INSERT, SELECT, DELETE ON TABLES TO db_writer;
ALTER DEFAULT PRIVILEGES IN SCHEMA schemaA GRANT SELECT ON TABLES TO db_reader;
Check this answer for more info

Postgresql permissions keep failing

I am running PostgreSQL 9.3.2 on Linux.
I have a group role 'data_scientist' and permissions to a particular (already populated) schema like so
grant usage on schema schemaname to data_scientist;
grant select, references, trigger
on all tables in schema schemaname
to data_scientist;
This fixes the problem of data_scientist using past tables. For future tables I added
alter default privileges in schema schemaname
grant select, references on tables
to data_scientist;
Still, whenever a new table is added, other data_scientist's permissions fail on the new tables.
By default, ALTER DEFAULT PRIVILEGES only applies to the role that ran the command. Suppose we have 2 users: ramfjord and animalito. If I (ramfjord) run
ALTER DEFAULT PRIVILEGES GRANT SELECT ON TABLES TO public; CREATE TABLE ramfjord_table;
Then animalito will be able to see it. If animalito runs
CREATE TABLE animalito_table
Then ramfjord won't be able to see it, because ramfjord's default privileges don't apply. See default privileges and their owners with \ddp
Because of this, we've stopped using default privileges at my company, and started using explicit GRANT's. To remove default privs, you have to run
ALTER DEFAULT PRIVILEGES FOR ROLE <owner> REVOKE...
The owner, schema, relation type and privileges have to match those listed in \ddp for this command to do anything. Do not just delete everything from the internal table that stores default privileges... trust me.