简体   繁体   中英

Postgres default privileges for readonly role

I have created a PostgreSQL (version 11.5) database and I want to create two different types of main roles ( readonly and readwrite ) and then assign these roles to individuals ( user1 , user2 , etc.).

I have been reading the PostgreSQL documentation and following this article as an example: https://aws.amazon.com/blogs/database/managing-postgresql-users-and-roles/

However, I have not been able to get the permissions set correctly. Basically, I want the role readwrite to be able to create any schema and/or tables they want within this database, and I want the role readonly to be able to SELECT from any of the schemas and/or tables in this database. However, following my example below, user2 can create a table, but user1 does not have access to that table.

I have created the following script that I can run as the master user for the database to create the database, schema, and roles.

Command to run SQL script:

psql -h <INSERT HOST HERE> -U postgres -W -f create_db.sql

Contents of create_db.sql

-- drop the existing database
DROP DATABASE IF EXISTS new_db;

-- create the database
CREATE DATABASE new_db;

-- connect to the database
\c new_db

-- create the new schema
CREATE SCHEMA new_schema;

-- revoke privileges from 'public' role
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE new_db FROM PUBLIC;

-- create readonly role
DROP ROLE IF EXISTS readonly;
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE new_db TO readonly;
GRANT USAGE ON SCHEMA new_schema TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA new_schema TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT ON TABLES TO readonly;

-- create read/write role
DROP ROLE IF EXISTS readwrite;
CREATE ROLE readwrite;
GRANT CONNECT, CREATE ON DATABASE new_db TO readwrite;
GRANT USAGE, CREATE ON SCHEMA new_schema TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA new_schema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA new_schema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT USAGE ON SEQUENCES TO readwrite;

-- create users
DROP USER IF EXISTS user1;
DROP USER IF EXISTS user2;
CREATE USER user1 WITH PASSWORD 'password';
CREATE USER user2 WITH PASSWORD 'password';

-- grant privileges to users
GRANT readonly TO user1;
GRANT readwrite TO user2;

After the script successfully runs, I can run the following script as user2 to create a table in the new schema.

Command to run SQL script

psql -h <INSERT HOST HERE> -d new_db -U user2 -W -f create_.sql

Contents of create_table.sql

-- drop the existing table
DROP TABLE IF EXISTS new_schema.new_table;

-- create a new table
CREATE TABLE new_schema.new_table (name VARCHAR, age INT);

-- insert data into the new table
INSERT INTO new_schema.new_table (name, age) VALUES ('Bob', 42);

Now, if user1 (readonly) logs into the database, I would hope they would be able to SELECT from this newly created table, however, it appears they do not have the correct access. They are able to see the table, but not query it.

psql -h <INSERT HOST HERE> -d new_db -U user1 -W
new_db=> \dt new_schema.*
           List of relations
   Schema   |   Name    | Type  | Owner 
------------+-----------+-------+-------
 new_schema | new_table | table | user2
(1 row)

new_db=> SELECT * FROM new_schema.new_table;
ERROR:  permission denied for table new_table

With PostgreSQL 11.7 it works with the following modifications:

  1. either the newly created table must be created by postgres user
  2. or running ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT ON TABLES TO readonly; must be run by user2 .

For example if I run create_table.sql as user2 with the above modification:

ALTER DEFAULT PRIVILEGES IN SCHEMA new_schema GRANT SELECT ON TABLES TO readonly;
ALTER DEFAULT PRIVILEGES

CREATE TABLE new_schema.new_table (name VARCHAR, age INT);
CREATE TABLE

INSERT INTO new_schema.new_table (name, age) VALUES ('Bob', 42);
INSERT 0 1

$ psql -U user1 -d new_db
psql (11.7)
Type "help" for help.

new_db=> select * from new_schema.new_table;
 name | age 
------+-----
 Bob  |  42
(1 row)


new_db=> \dp+ new_schema.new_table;
                                  Access privileges
   Schema   |   Name    | Type  |  Access privileges  | Column privileges | Policies 
------------+-----------+-------+---------------------+-------------------+----------
 new_schema | new_table | table | readonly=r/user2   +|                   | 
            |           |       | user2=arwdDxt/user2 |                   | 
(1 row)

I understand that ALTER DEFAULT PRIVILEGES must be run by the owner of the future involved objects.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM