Postgresql permissions keep failing - sql

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.

Related

PostgreSQL - Why a privileged user can't access newly created partition

Why a privileged user can't access newly created partition?
PostgreSQL version: 10.0
Suppose my PostgreSQL sever has a user called app with following permissions:
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public TO app;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public to app;
Now this user app can do select, insert and update action for "existing" table/partition (for example: mytable_partition_old) just as my expectation, everything goes well so far.
However, a master account creates a new partition of a table after the GRANT command above by following:
CREATE TABLE IF NOT EXISTS "mytable_partition_new" PARTITION OF mytable FOR VALUES IN('some_value');
After mytable_partition_new is created, the user app got "permission denied for this relation" by executing INSERT INTO mytable_partition_new values (...) command.
I understand it can be resolved by issue GRANT SELECT, .... TO app again.
My question is if there any better way to achieve it?
(we don't have a dedicated DBA and got stucked in this situation for a while..)
The GRANTs you have shown, only granted the privileges for existing objects. To grant the privileges for "future" objects, you need to alter the default privileges:
alter default privileges in schema public
for role master
GRANT SELECT, INSERT, UPDATE ON TABLES TO app;
alter default privileges in schema public
for role master
GRANT USAGE ON SEQUENCES TO app;
The above will only affect future objects, so for the tables (or partitions) you have already created, you need to re-run you original GRANT statements once again.

Is there a way to grant permissions on tables that don't exist yet (or that get recreated)?

I have a database with a read-only role set up; let's call it 'app_user_ro'. I am using a third party data loading tool (running as 'app_user') that drops and recreates the tables. After recreating the tables, the previous permissions are gone and 'app_user_ro' can no longer select from the tables.
I am using Postgres 11.3 running on Ubuntu 19.04. I've looked at Grant privileges on future tables in PostgreSQL? and tried altering the default privileges but still 'app_user_ro' can't read data from the tables after they are dropped and recreated.
I've tried:
-- The accepted answer
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO app_user_ro;
-- An alternative answer from the comments:
ALTER DEFAULT PRIVILEGES FOR USER app_user_ro IN SCHEMA public GRANT SELECT ON TABLES TO app_user_ro;
The only thing that works is manually granting the permissions after each import:
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_user_ro;
The docs state:
You can change default privileges only for objects that will be created by yourself or by roles that you are a member of
The roles I had were:
app_data_loader=# \du
List of roles
Role name | Attributes | Member of
----------------+------------------------------------------------------------+------------
app_user | | {postgres}
app_user_ro | | {}
pg | Superuser | {}
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {}
Originally I was running the ALTER DEFAULT... commands as the 'postgres' role but more recently I added the 'app_user_ro' role to the 'app_user' role (the one loading the data) and tried running it as the 'app_user' role with no change in behaviour.
For now I'll just schedule a job to grant the permissions after each import but it seems like there should be a better way!
The puzzle piece you are missing is that ALTER DEFAULT PRIVILEGES only affects tables that get created by the role specified in the FOR USER/ROLE clause (or, if you omit that, by the user who ran the statement).
So if it is app_user that creates the tables, you'll have to run
ALTER DEFAULT PRIVILEGES FOR ROLE app_user ...;

alter default privileges of certain column

I want a RoleGroup to have certain privileges on a specific column in a table ….the roleGroup not DB owner :
grant SELECT, INSERT ,UPDATE (colOne) on table schemaOne.tableOne
to roleGroup;
When I want alter default privileges of this column (to include future users), I get ERROR saying can’t alter default privileges of one column only :
alter default privileges for role DB_OWNER in schema schemaOne grant
select,insert,update(colOne) on table schemaOne.tableOne to
roleGroup;
which forced me to do this :
Alter Default priviliges for role DB_OWNER in schema schemOne grant
select,insert,update to roleGroup ;
what’s the point of the first grant then ?!! Or am I making some mistake ?
The whole question is a bit unclear as both of your statements are syntactically incorrect.
GRANT grants privileges on existing objects, while ALTER DEFAULT PRIVILEGES defines what privileges will automatically be granted to objects created in the future. So the scope of these statements does not overlap, but they complement each other.
I guess you misunderstood that point, otherwise you wouldn't try to ALTER DEFAULT PRIVILEGES on an existing table.
A valid form would be:
ALTER DEFAULT PRIVILEGES FOR ROLE db_owner IN SCHEMA schemaone
GRANT INSERT, SELECT, UPDATE ON TABLES TO rolegroup;
This will grant the privileges on all tables created in that schema by db_owner in the future.
The title of your question suggests that you are wondering why you cannot use ALTER DEFAULT PRIVILEGES to grant privileges on columns.
The likely answer is that not all future tables need to have a column colone, and what should happen with tables that don't have a column of that name. You might argue that no privileges should be granted in that case, and I guess that is a valid option. But it seems hard to come up with a use case for that, which may explain why nobody has considered implementing such a feature so far.
Alternatively, your desire could be that a column that will be added to an existing table in the future should automatically receive the privileges, but again I don't consider such a feature as very useful.

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

Grant privileges on future tables in PostgreSQL?

I am running PostgreSQL 9.3.1. I have test database and backup user which is used to backup the database. I have no problems with granting privileges to all current tables, but I have to grant privileges each time the new table is added to schema.
createdb test
psql test
test=# create table foo();
CREATE TABLE
test=# grant all on all tables in schema public to backup;
GRANT
test=# create table bar();
CREATE TABLE
psql -U backup test
test=> select * from foo;
test=> select * from bar;
ERROR: permission denied for relation bar
Is it possible to grant access to tables which will be created in future without making user owner of the table?
It looks like the solution is to alter default privileges for backup user:
alter default privileges in schema public grant all on tables to backup;
alter default privileges in schema public grant all on sequences to backup;
From the comment by Matt Schaffer:
As caveat, the default only applies to the user that executed the
alter statement. This confused me since I was driving most of my
permissions statements from the postgres user but creating tables from
an app user. In short, you might need something like this depending on
your setup:
ALTER DEFAULT PRIVILEGES FOR USER webapp IN SCHEMA public GRANT SELECT ON SEQUENCES TO backup;
ALTER DEFAULT PRIVILEGES FOR USER webapp IN SCHEMA public GRANT SELECT ON TABLES TO backup;
Where webapp is the user that will be creating new tables in the futrue and backup is the user that will be able to read from new tables created by webapp.
If you want the backup user to have access to the future tables of userN,
you must run the code below under each userN who creates new tables,
because ALTER DEFAULT PRIVILEGES...
works only for objects by that user under whom you run ALTER DEFAULT PRIVILEGES...
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO backup;
I am trying to create a role, grant connect access to the role and then alter default privileges to keep access for future objects. However, it seems that the below command doesn't work at role level.
alter default privileges in schema public grant all on tables to backup;
I followed the below documentation but seems that there are two command do not work for roles.
DOC: https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/
First command:
GRANT CONNECT ON DATABASE mydatabase TO readonly;
Second command:
GRANT USAGE ON SCHEMA myschema TO readonly;
(For ROLES usually it needs TO ROLE, I also tried TO ROLE but still doesn't work.