User management + grant - sql

I have a database with multiple tables, functions, sequences, and types inside.
I want to create multiple "administrator"-like users:
they all might have all privileges to manage everything (existing and newly created items) in this database;
they all have the same privileges;
they might cross-manage entities (table created by administrator a should be available for a removal for administrator b)
I tried to create something like this, but failed on types:
"GRANT ALL PRIVILEGES ON DATABASE {dbname} TO {rw_user};"
"GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO {rw_user};"
"GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO {rw_user};"
"GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO {rw_user};"
"GRANT ALL PRIVILEGES ON ALL TYPES IN SCHEMA public TO {rw_user};" --not exists
"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TABLES TO {rw_user};"
"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON SEQUENCES TO {rw_user};"
"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON FUNCTIONS TO {rw_user};"
"ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL PRIVILEGES ON TYPES TO {rw_user};"

The only way I can think of to do that (if you don't want a shared database user) is the following:
CREATE ROLE admins;
CREATE ROLE a LOGIN NOINHERIT IN ROLE admins;
CREATE ROLE b LOGIN NOINHERIT IN ROLE admins;
CREATE SCHEMA shared;
GRANT CREATE; USAGE ON SCHEMA shared TO admins;
Then neither a nor b can create objects in shared unless they do the following:
SET ROLE admins;
CREATE TABLE shared.newtab (...);
RESET ROLE;
Such a table is then owned by admins, and both a and b can ALTER or DROP it.
Note that ALTER and DROP are restricted to the owner of the object, and you cannot GRANT these rights.

Related

postgres: how to create role with insert and update access

I have a user db_owner who is owner to my database called 'Sales'.
Now i have to create two groups(sales_ro and sales_riu) and then i will add users to this groups.
sales_ro group should inherit(from db_owner) read access on tables and execute on functions in Sales db
sales_riu group should inherit(from db_owner) insert and update access on tables and execute on functions in Sales db.
can we create such two groups in Postgres ?
You don't need to create groups to achieve this. You can just create Roles and assign them to the users you want. For example:
CREATE ROLE sales_ro;
CREATE ROLE sales_riu;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO sales_ro;
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO sales_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO sales_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO sales_ro;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE ON TABLES TO sales_riu;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT EXECUTE ON FUNCTIONS TO sales_riu;
After that just grant role to expected users:
GRANT sales_ro TO your_user_1;
GRANT sales_riu TO your_user_2;
Please refer link 1 and link 2 to know more about ALTER DEFAULT PRIVILEGES and CREATE ROLE respectively.
Quoting below points from above links:
CREATE ROLE adds a new role to a PostgreSQL database cluster. A role
is an entity that can own database objects and have database
privileges; a role can be considered a “user”, a “group”, or both
depending on how it is used.
A role having the LOGIN attribute can be thought of as a user. Roles
without this attribute are useful for managing database privileges

Preventing users from altering default privileges on PostgreSQL

I'm testing database permissions on PostgreSQL and i'm trying to prevent a common user (readuser) from executing an 'ALTER DEFAULT PRIVILEGES' statement. However i cannot find a way to revoke this specific permission, and couldn't find anything about it on documentation.
I started a local PostgreSQL 11.2 instance, removed connect permisssions, created a database testdb and revoked table creation on the public schema.
revoke connect on database postgres from public;
create database testdb with template template0 --lc_collate "pt_BR.utf8" lc_ctype "pt_BR.utf8";
revoke connect on database testdb from public;
\c :database
revoke all on schema public from public;
grant all on schema public to postgres;
create schema private;
After that, I created a user with read permissions only:
create user readuser
with nosuperuser
nocreatedb
nocreaterole
noreplication
login
encrypted password 'testpassword';
grant connect
on database testdb
to readuser;
Then create a schema testschema and granted read permissions on it's tables:
grant usage
on schema testschema
to readuser;
grant select
on all tables
in schema testschema
to readuser;
Even though i only set read permissions on all schemas and tables, the 'readuser' user can still perform 'alter default privileges' query without a permission error:
alter default privileges in schema testschema grant select on tables to readuser;
ALTER DEFAULT PRIVILEGES
I would like some help on preventing a user from altering it's default privileges, so that it cannot mess up permissions for tables created in the future.
Try this by revoking the EXECUTE from the role postgres that granted the default privilege of execute to readuser
ALTER DEFAULT PRIVILEGES FOR ROLE postgres IN SCHEMA testschema REVOKE EXECUTE ON FUNCTIONS FROM readuser;

postgres new schema to inherit permissions for a user

I have a created read only user with below commands
CREATE ROLE read_only WITH LOGIN PASSWORD 'password'
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL
'infinity';
Then I gave select permision
GRANT USAGE ON SCHEMA public TO read_only;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO read_only;
GRANT SELECT ON ALL TABLES IN SCHEMA public to read_only;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO
read_only;
My requirement is whenever there is a new schema added it should inherit the permissions for read_only user. Currently I manually assign these permissions for new schema.
There is no way to do that automatically, you will have to continue doing that explicitly.

how can I create role groups in postgresql

I can create a role in postgresql.
CREATE ROLE myname WITH LOGIN PASSWORD 'pass';
and I can set privilages on a database schema for this user.
GRANT USAGE ON SCHEMA public TO myname;
and select privilages to a user.
GRANT SELECT ON ALL TABLES IN SCHEMA public TO myname;
But I have so many users in my database. I do not want to set these privilages to all of my users. Actually I want to create role groupnames:
viewer
editor
admin
And
viewer will be select privilages on all tables,
editor will be select, insert and update privilages on all tables.
my users will be in these groups.
How can I do this?
CREATE ROLE viewer;
CREATE ROLE editor;
CREATE ROLE admin;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO viewer;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO viewer;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT,INSERT,UPDATE ON TABLES TO editor;
GRANT some_other_privs_to_admin_group
after that just grant group to user:
GRANT editor TO your_user;
and so on
https://www.postgresql.org/docs/current/static/sql-alterdefaultprivileges.html
https://www.postgresql.org/docs/current/static/sql-createrole.html
CREATE ROLE adds a new role to a PostgreSQL database cluster. A role
is an entity that can own database objects and have database
privileges; a role can be considered a “user”, a “group”, or both
depending on how it is used.
and
A role having the LOGIN attribute can be thought of as a user. Roles
without this attribute are useful for managing database privileges
For this very reason it is advisable to use "groups", that is roles (usually with NOLOGIN) to which you add the users (by granting the role to them).
In your case:
CREATE ROLE viewer;
GRANT <whatever> TO viewer;
GRANT viewer TO myname;
Then myname will enjoy all the privileges granted to viewer, and you don't have to mess around with granting and revoking privileges to every user.

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.