Problem
How do i create a read-only user ? The user ( non-superuser ) with connect permission on the database is able to create / drop object on the database , how do we restrict them from doing so ?
Solution
By default any user that is allowed to connect to the database can create object in the public schema , you can use the below query to check who can connect under the column "rolcanlogin"
SELECT * FROM pg_roles;
So if you wish users to avoid creating a table , you will need to revoke first permission from public through this command below after connecting to the database.
REVOKE ALL ON schema public FROM public;
This will make only gpadmin ( superuser ) create objects under the database in question , but if you wish other user to create object in it as well , you would have to grant them separatly / manually like
GRANT ALL ON schema public TO;
Example
Now lets take a example to understand the scenario better.
First lets check who can create object under a database in the public schema .
gpadmin=# select * from pg_namespace where nspname='public'; nspname | nspowner | nspacl ---------+----------+------------------------------------------------ public | 10 | {gpadmin=UC/gpadmin,a2=UC/gpadmin,=UC/gpadmin} (1 row)
from the above example the column "nspacl" shows a entry of "=UC/gpadmin" , note there is no value before the last "="" sign , which means any one can create objects under this public schema.
Revoke the grant and verifying it , shows now no one can create object under it
gpadmin=# REVOKE ALL ON schema public FROM public; REVOKE Time: 299.719 ms gpadmin=# select * from pg_namespace where nspname='public'; nspname | nspowner | nspacl ---------+----------+------------------------------------ public | 10 | {gpadmin=UC/gpadmin,a2=UC/gpadmin} (1 row) Time: 23.899 ms gpadmin=#
Connecting as non-superuser a1 and attempting to create a table , throws out error like below.
gpadmin:Fullrack@mdw $ psql -U a1 Password for user a1: Timing is on. Pager usage is off. psql (8.2.15) Type "help" for help. gpadmin=> create table test1111 as select * from pg_class; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'relname' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. ERROR: no schema has been selected to create in gpadmin=>
As gpadmin ( superuser ) , grant specfic users/role to create object under the schema
gpadmin=# GRANT ALL ON schema public TO a1; GRANT Time: 125.443 ms gpadmin=# select * from pg_namespace where nspname='public'; nspname | nspowner | nspacl ---------+----------+-------------------------------------------------- public | 10 | {gpadmin=UC/gpadmin,a2=UC/gpadmin,a1=UC/gpadmin} (1 row) Time: 22.500 ms gpadmin=# \q gpadmin:Fullrack@mdw $ psql -U a1 Password for user a1: Timing is on. Pager usage is off. psql (8.2.15) Type "help" for help. gpadmin=> create table test1111 as select * from pg_class; NOTICE: Table doesn't have 'DISTRIBUTED BY' clause -- Using column(s) named 'relname' as the Greenplum Database data distribution key for this table. HINT: The 'DISTRIBUTED BY' clause determines the distribution of data. Make sure column(s) chosen are the optimal data distribution key to minimize skew. SELECT 508 Time: 3921.078 ms