Why doesnt ALTER DEFAULT PRIVILEGES work as expected? - postgresql

I have 2 users. User1 is writing and member of the role writing, while User2 is member of the role "reader".
The reader role received subsequent permissions:
GRANT CONNECT ON DATABASE to reader
GRANT USAGE ON SCHEMA x TO reader
I want the reader to be able to read/select all existing and new tables from the given schema but using
ALTER DEFAULT PRIVILEGES IN SCHEMA x GRANT SELECT ON TABLES TO reader;
does't work. User2 won't receive any permission for new tables created by User1/the writer role.
Using:
ALTER DEFAULT PRIVILEGES FOR ROLE writer IN SCHEMA x GRANT SELECT ON TABLES TO reader;
doesn't work either. I have to explitly name the Owner of that table. To solve this I had to use:
ALTER DEFAULT PRIVILEGES FOR ROLE User1 IN SCHEMA x GRANT SELECT ON TABLES TO reader;
which I actually don't want, because there may be other users than User1 who are going to publish tables into that schema as well.
Am I missing anything?

Related

Grant readaccess to all existing (and future) Postgres schematas

I have a Postgres database (PostgreSQL-Version 11), which has a lot schematas. Each schemata has a lot of tables. So, now I've got a user xyz, which should have readaccess to all of those schematas and all future ones. I found this gist, which explains how to create a readaccess group and how to add a user to this group:
-- Create a group
CREATE ROLE readaccess;
-- Grant access to existing tables
GRANT USAGE ON SCHEMA public TO readaccess;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readaccess;
-- Grant access to future tables
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readaccess;
-- Create a final user with password
CREATE USER tomek WITH PASSWORD 'secret';
GRANT readaccess TO xyz;
But this is only working for the public schemata. Lets assume, i create a new schemata called "new_schema", the user xyz don't have readaccess to this this schema.
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readaccess;
is creating readaccess to all future tables inside a specific schemata, but not for future schematas.
Long story short: How can i give readaccess to all existing and future schematas for a specific user?

How to grant permissions to user for current schemas and schemas created in the future?

I have a Postgres database and a read-only user that I want to grant permissions to. I have two schemas currently but expect to make many more in the future. How do I grant select permissions to my read-only user so that they can read data from the tables that are currently created as well as tables that will be created in a new schema in the future?
I don't want to have to explicitly grant permissions for each new schema when they are created.
Use ALTER DEFAULT PRIVILEGES without specifying any schema:
The privileges can be set globally (i.e., for all objects created in the current database) […]
If IN SCHEMA is omitted, the global default privileges are altered.
So this should do it:
ALTER DEFAULT PRIVILEGES FOR whoever_will_create_the_tables
GRANT SELECT ON TABLES TO the_readonly_user;
ALTER DEFAULT PRIVILEGES FOR whoever_will_create_the_schemas
GRANT USAGE ON SCHEMAS TO the_readonly_user;
Granting the privilege on the tables that already are created needs a separate statement:
GRANT SELECT ON ALL TABLES IN SCHEMA schema_1, schema_2 TO the_readonly_user;

Restrict create table privilege to newly created users in RDS PostgreSQL 9.6

I am facing an issue while creating a readonly users in RDS PostgreSQL 9.6. I am executing the following SQL commands:
---- ###### CREATE ROLE ################
CREATE ROLE readonlyrole_dev;
-- Grant access to existing tables
GRANT USAGE ON SCHEMA public TO readonlyrole_dev;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyrole_dev;
-- set the privileges that will be applied to objects created in the future.
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO readonlyrole_dev;
CREATE USER readonly_dev WITH PASSWORD 'welcome1';
GRANT readonlyrole_dev TO readonly_dev;
When I login with the readonly_dev user, it has privilege to create the new tables by default but I don't want to do that. I want to keep readonly_dev only a read only user.
Note: To revoke the access from the user I am executing
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
which revokes create objects privilege to all old users as well. I only want to revoke create privilege from newly created user.
How can I do that?
You cannot do that, and it is not necessary either.
Just deny the user the CREATE permission on all schemas. You should use user groups for that - put all users who should have the privilege to create tables in a group that has the required privilege on the schema and revoke CREATE from PUBLIC.
If you insist that you must have this, try creating an event trigger that throws an exception whenever a certain user tries to create a table.

Create aws redshift user with access to given schema including drop tables

I would like to seperate access to two existing data schemas (with tables already created) in redshift by creating two new users and granting them access to their relevant schemas.
So user_1 should have access only to schema_1 and user_2 should have access only to schema_2.
By access I mean that the users should be able to SELECT, INSERT, UPDATE, DELETE, DROP from all current tables (no matter who created them) and to CREATE new tables on their schemas.
I have found the below statements to create a new user and to give them specific access types:
Create new user:
CREATE USER user_1 WITH PASSWORD 'password_1';
Grant usage to the given schema:
GRANT USAGE ON SCHEMA "schema_1" TO user_1;
Assign privileges:
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA "schema_1" TO user_1;
Alter Default Privileges to maintain the permissions on new tables
ALTER DEFAULT PRIVILEGES IN SCHEMA "schema_1" GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO user_1;
In the documentation it shows how to add all privileges required except for DROP tables. When testing this it errors with ERROR: must be owner of relation table_to_drop.
I alternatively have tried to grant all privileges as below...
GRANT ALL TABLES IN SCHEMA "schema_1" TO user_1;
...but this doesn't overwrite the requirement of it needing to be the owner of the table that drops is able to drop it.
So question is is it possible to restrict a user to a given schema with acccess to it as mentioned above?
Only the owner of the table, the schema owner, or a superuser can drop a table. So user_1 should be the owner of schema_1 and user_2 should be the owner of schema_2 if you want them to be able to drop tables in their respective schema.
I am assuming that user_1 and user_2 are not superusers or the question is moot.

Postgres create database user with grant access to schema only

I have a database with a template_schema.I cloned this template schema and created a database user with password. I need to provide access to cloned schema only, for the created user.
SELECT clone_schema('my_template_schema','john_smith_gmail_com');
CREATE USER john_smith_gmail_com WITH PASSWORD 'mypassword';
Upto this Ok. Then I need to grant access to this user for this cloned schema(john_smith_gmail_com) only
Method :1
I tried to revoke all privileges on all tables of cloned schema(john_smith_gmail_com) for the user and grant select to the user. But my question is, can this user get SELECT access on other schema tables?
REVOKE ALL ON ALL TABLES IN SCHEMA john_smith_gmail_com FROM john_smith_gmail_com;
GRANT SELECT ON ALL TABLES IN SCHEMA john_smith_gmail_com TO john_smith_gmail_com;
Method :2
Create a role with only SELECT access and assign or grant this role to newly created user. If I do this, for which schema I grant access,because I clone schema dynamically?
Which method is best one?
From postgresql version 9.0 and forward, the best way is probably to use ALTER DEFAULT PRIVILEGES.
...the default privileges for any object type normally grant all grantable permissions to the object owner, and may grant some privileges to PUBLIC as well. However, this behavior can be changed by altering the global default privileges with ALTER DEFAULT PRIVILEGES.
So if all users like "john_smith_gmail_com" should only have SELECT access to tables in "their own" schema, after creating the schema and user, you can run:
ALTER DEFAULT PRIVILEGES IN SCHEMA john_smith_gmail_com GRANT SELECT ON TABLES TO john_smith_gmail_com;