I would like to set default ACL for all roles (i.e. without using PUBLIC) in PostgreSQL and want to avoid enumerating.
Is there an easy way to do that?
You can do this in the following way:
Grant SELECT privilege to everyone for all tables (and views) you subsequently create in schema myschema:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT SELECT ON TABLES TO PUBLIC;
and allow role webuser to INSERT into them too:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema GRANT INSERT ON TABLES TO webuser;
and to Undo the above:
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE SELECT ON TABLES FROM PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA myschema REVOKE INSERT ON TABLES FROM webuser;
Source
That's it :)
Related
I have a postgresql (v10) database. I've created database tn_beta_db with schema tn_schema. I've created three users and executed the following, which is meant to grant all of them read and maybe modify access on all tables, current and future that tn_beta_migrator might create.
\c tn_beta_db
-- User tn_beta_reader --
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_reader GRANT SELECT ON TABLES TO tn_beta_reader;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_reader;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_reader;
-- User tn_beta_migrator --
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_migrator GRANT ALL ON TABLES TO tn_beta_migrator;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_migrator;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_migrator;
GRANT ALL ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_migrator;
GRANT CREATE ON SCHEMA tn_schema TO tn_beta_migrator;
-- User tn_beta_writer --
ALTER DEFAULT PRIVILEGES IN SCHEMA tn_schema FOR ROLE tn_beta_writer GRANT SELECT,INSERT,DELETE,UPDATE ON TABLES TO tn_beta_writer;
GRANT CONNECT ON DATABASE tn_beta_db TO tn_beta_writer;
GRANT USAGE ON SCHEMA tn_schema TO tn_beta_writer;
GRANT SELECT,INSERT,DELETE,UPDATE ON ALL TABLES IN SCHEMA tn_schema TO tn_beta_writer;
If I now connect as tn_beta_migrator, I can create a table and do things with it.
create table tn_schema.foo(x int);
-- and then INSERT, SELECT, UPDATE, even DROP
But now if I connect as either of tn_beta_reader or tn_beta_writer, I can not use that table.
tn_beta_db=> select * from tn_schema.foo ;
ERROR: permission denied for relation foo
tn_beta_db=>
I would expect to be able to read/write/modify/delete as tn_beta_writer and to be able to read as tn_beta_reader.
If I rerun the grant script, above, this permits me to access foo, but a newly created table bar would then be inaccessible.
I'd thought that the alter default privileges commands would permit these roles, in the future, to access the tables created by tn_beta_migrator.
Any pointers on what I've misunderstood?
The role in the FOR ROLE clause in ALTER DEFAULT PRIVILEGES is not the role that will get the privileges, it is the role that creates the tables.
So your statements should start with
ALTER DEFAULT PRIVILEGES FOR ROLE tn_beta_migrator ...
I have to create one database[myDB] and one custom schema[mySchema] not the public one.
Where did I go wrong:
I created 3 users: user_admin, user_rw, user_ro, which will be given access alter.
Now, I login with my super user: postgres [I am using postgres 11 on GCP] through cloud shell.
Created the my database: myDB, I went into myDB. And i fired below commands for all 3 users access.
# for admin user
GRANT CONNECT ON DATABASE myDB TO user-admin;
GRANT USAGE ON SCHEMA mySchema TO user-admin ;
GRANT ALL PRIVILEGES ON SCHEMA mySchema TO user-admin ;
GRANT ALL ON ALL TABLES IN SCHEMA mySchema TO user-admin ;
GRANT ALL ON ALL SEQUENCES IN SCHEMA mySchema TO user-admin ;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA mySchema TO user-admin ;
ALTER DEFAULT PRIVILEGES IN SCHEMA mySchema GRANT ALL PRIVILEGES ON TABLES TO user-admin;
# for read write user
GRANT CONNECT ON DATABASE myDB TO user-rw;
GRANT USAGE ON SCHEMA mySchema TO user-rw ;
GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA mySchema TO user-rw ;
GRANT SELECT,UPDATE ON ALL SEQUENCES IN SCHEMA mySchema TO user-rw ;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA mySchema TO user-rw ;
ALTER DEFAULT PRIVILEGES IN SCHEMA mySchema GRANT SELECT,INSERT,UPDATE ON TABLES TO user-rw;
# for read only user
GRANT CONNECT ON DATABASE myDB TO user-ro;
GRANT USAGE ON SCHEMA mySchema TO user-ro ;
GRANT SELECT ON ALL TABLES IN SCHEMA mySchema TO user-ro ;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA mySchema TO user-ro ;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA mySchema TO user-ro ;
ALTER DEFAULT PRIVILEGES IN SCHEMA mySchema GRANT SELECT ON TABLES TO user-ro;
Till this point i did not have any issue.
I created the table in mySchema with the help of user-admin, this would work like this in future as well.
And rest two users will use just for read and another for read write.
The problem is I can not able to see the created table from other users included postgres, user-rw, user-ro but only owner which was user-admin is having access to do all the operations like create and drop.
Also, after creating the table from admin user, when i rerun below command, it gives me permission denied.
GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA mySchema TO user-rw ;
Please let me know what i am doing wrong.
GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA mySchema TO user-rw ;
VS
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA mySchema TO user-rw ;
first option gives privileges to exist tables, the second option give you permission to exist ones and the new ones that i will be created in the future,
but he best approach is not apply this permissions direct to the user, create a group and grant the permissions there and assign the group to the user, the reason if you want to drop the user first u need to drop all the privileges created and after u can drop the user.
Also, after creating the table from admin user, when i rerun below
command, it gives me permission denied.
GRANT SELECT,INSERT,UPDATE ON ALL TABLES IN SCHEMA mySchema TO user-rw
;
about this part make sure u are using the admin to give permission.
I am setting up a Postgres DB (AWS/RDS) with multiple schemas and want to have granular access control.
Each schema correlates to an application. Typically an application will have a "write" user (INSERT, UPDATE, DELETE etc.), but some applications only needs to read (SELECT) from different schemas.
Inspired by this AWS blog: https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/
I face problems with "permission denied" for my readusers querying tables created by writeusers, even though I ALTER DEFAULT PRIVILEGES:
ALTER DEFAULT PRIVILEGES IN SCHEMA someschema GRANT SELECT ON TABLES TO some_read_role;
Steps to reproduce:
Create AWS RDS postgres (10.6) instance with masteruser postgres
(DB postgres) As user postgres:
CREATE DATABASE somedb LC_COLLATE 'da_DK.utf8' LC_CTYPE 'da_DK.utf8' ENCODING 'UTF8' TEMPLATE template0;
(DB somedb) As user postgres:
REVOKE ALL ON DATABASE somedb FROM PUBLIC;
CREATE SCHEMA clients;
CREATE ROLE clients_read_role;
GRANT CONNECT ON DATABASE somedb TO clients_read_role;
CREATE ROLE clients_write_role;
GRANT CONNECT ON DATABASE somedb TO clients_write_role;
GRANT USAGE ON SCHEMA clients TO clients_read_role;
GRANT SELECT ON ALL TABLES IN SCHEMA clients TO clients_read_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA clients GRANT SELECT ON TABLES TO clients_read_role;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA clients TO clients_read_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA clients GRANT SELECT ON SEQUENCES TO clients_read_role;
GRANT USAGE, CREATE ON SCHEMA clients TO clients_write_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA clients TO clients_write_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA clients GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO clients_write_role;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA clients TO clients_write_role;
ALTER DEFAULT PRIVILEGES IN SCHEMA clients GRANT USAGE ON SEQUENCES TO clients_write_role;
(DB somedb) As user postgres:
CREATE USER clients_read WITH PASSWORD 'xxx';
GRANT clients_read_role TO clients_read;
CREATE USER clients_write WITH PASSWORD 'yyy';
GRANT clients_write_role TO clients_write;
(DB somedb) As user clients_write (via LiquiBase):
CREATE TABLE clients.sometable
(
id serial primary key,
name varchar(50) not null
);
(DB somedb) as user clients_read:
SELECT * FROM clients.sometable;
[42501] ERROR: permission denied for relation sometable
From the docs:
You can change default privileges only for objects that will be
created by yourself or by roles that you are a member of.
In other words, running ALTER DEFAULT PRIVILEGES as user postgres only affects tables created by postgres.
To change the defaults for another user's tables, you need to specify which user:
ALTER DEFAULT PRIVILEGES FOR ROLE clients_write ...
Note that the defaults are not inherited, so the target role is clients_write (i.e. the user actually running the CREATE TABLE command, who will become the new table's owner). Defaults for clients_write_role will have no effect unless your users SET ROLE clients_write_role; before creating a table.
I am trying to create a read-only user in PostgreSQL and I have done so, with the only caveat being that my new read-only user is able to create temporary tables. How?? Why??
I have specifically run:
CREATE ROLE read_access LOGIN;
REVOKE CREATE ON SCHEMA public FROM public;
GRANT USAGE ON SCHEMA {schema_name} TO read_access;
GRANT SELECT ON ALL TABLES IN SCHEMA {schema_name} TO read_access;
ALTER DEFAULT PRIVILEGES IN SCHEMA {schema_name}
GRANT SELECT ON TABLES TO read_access;
You are missing one permission:
REVOKE TEMPORARY ON DATABASE {dbname} FROM PUBLIC;
By default, the special role PUBLIC, to which everybody automatically belongs, is allowed to create temporary tables.
Is it possible to alter default priviledges on PostgreSQL role, such that role has SELECT on any table in any schema (existing or created in future)
I have 3 roles (app_r is member of app_rw which is member of app_rwc)
and I am trying this:
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT USAGE ON SCHEMAS TO app_r;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT SELECT ON TABLES TO app_r;
but it does not work.
SELECT has_table_privilege('app_r', 'some_schema.some_table', 'SELECT')
-- false
Is there a way to do this in PG or do I have to use IN SCHEMA and repeat for every schema? (ughhh)
ALTER DEFAULT PRIVILEGES FOR ROLE app_r IN SCHEMA some_schema GRANT SELECT ON TABLES TO app_r;
P.S.
I did try running ALTER DEFAULT before (and after also, just to test) creating schemas and tables...
P.P.S
My role setup is inspired by this answer and I saw in this answer that is not necessary having to explicitly specify schemas
UPDATE #1 - Here is exact role setup I am using:
CREATE ROLE app_rwc INHERIT CREATEDB CREATEROLE;
CREATE ROLE app_rw INHERIT;
CREATE ROLE app_r INHERIT;
GRANT app_r TO app_rw;
GRANT app_rw TO app_rwc;
-- these must be performed *before* any objects are created
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT USAGE ON SCHEMAS TO app_r;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT SELECT ON TABLES TO app_r;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT INSERT, UPDATE, DELETE ON TABLES TO app_rw;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc REVOKE TRUNCATE ON TABLES TO app_rw;
ALTER DEFAULT PRIVILEGES FOR ROLE app_rwc GRANT SELECT, UPDATE ON SEQUENCES TO app_rw;
Is it possible to alter default priviledges on PostgreSQL role, such
that role has SELECT on any table in any schema (existing or created
in future)
As of version 9.6, no.