Postgres grant privileges issue - postgresql

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.

Related

Create roles and users only in a certain database and not in the default postgres database

I'm trying to setup a database with a readwrite user jirauser and a readonly user controlling_ro. This is my script to set it up based on this Blog article. testuser is the master user.
PGPASSWORD=XXX psql \
--dbname=postgres \
--host=XXX.XXX.eu-central-1.rds.amazonaws.com \
--port=5432 \
--username=testuser \
<<EOF
-- Clean DB
DROP DATABASE jiradb;
DROP USER jirauser;
DROP USER controlling_ro;
DROP SCHEMA jiraschema;
DROP ROLE readonly;
DROP ROLE readwrite;
-- Create DB
CREATE DATABASE jiradb;
\connect jiradb;
CREATE SCHEMA jiraschema;
-- Revoke privileges from 'public' role
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON DATABASE jiradb FROM PUBLIC;
-- Read-only role
CREATE ROLE readonly;
GRANT CONNECT ON DATABASE jiradb TO readonly;
GRANT USAGE ON SCHEMA jiraschema TO readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA jiraschema TO readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT SELECT ON TABLES TO readonly;
-- Read/write role
CREATE ROLE readwrite;
GRANT CONNECT ON DATABASE jiradb TO readwrite;
GRANT USAGE, CREATE ON SCHEMA jiraschema TO readwrite;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA jiraschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO readwrite;
GRANT USAGE ON ALL SEQUENCES IN SCHEMA jiraschema TO readwrite;
ALTER DEFAULT PRIVILEGES IN SCHEMA jiraschema GRANT USAGE ON SEQUENCES TO readwrite;
-- Users creation
CREATE USER controlling_ro WITH PASSWORD 'XXX';
CREATE USER jirauser WITH PASSWORD 'XXX';
-- Grant privileges to users
GRANT readonly TO controlling_ro;
GRANT readwrite TO jirauser;
EOF
After running this script I expect the roles and the users only to be in the jiradb database. However looking into the default database postgres with dbeaver they are also there. Does this mean they also have access to the postgres database?
That's just an artifact of your client tool.
In reality, PostgreSQL users don't belong to any database; they are shared by all databases. So no matter to which database you are connected when you create a user, it will equally exist for all databases.
You can use the CONNECT permission on the database object or (more typically) configure pg_hba.conf to determine which user can access which database.
According to https://www.postgresql.org/docs/current/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. Refer to Chapter 21 and Chapter 20 for information about managing users and authentication. You must have CREATEROLE privilege or be a database superuser to use this command.
Note that roles are defined at the database cluster level, and so are valid in all databases in the cluster.
So it's just your GUI misleading you.

PostgreSQL: roles can only access tables they've created

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 ...

Set default ACL for all currently defined roles in Postgres

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 :)

Postgres: GRANT usage on schema myschema to myrole; Error

I'm new to Postgres (worked with Oracle the last 23 years).
I would like to grant the usage on schema to role. But that seems to be impossible:
ps >create role marco_role;
CREATE ROLE
ps >create schema myschema;
CREATE SCHEMA
ps >grant usage on myschema to marco_role;
FEHLER: Relation »myschema« existiert nicht (English: Relation does not exists)
What is my problem?
To grant privileges on a schema you need to use ON SCHEMA as documented in the manual
grant usage ON SCHEMA myschema to marco_role;
You probably also want to define default privileges for new tables (that are not yet created) as well:
alter default privileges
in schema myschema
grant select on tables to marco_role;

Grant access to views in postgresql

I have a view called testview in postgresql.
I created a new user called testuser.
I would like testuser to have all privileges on all tables and views in the database.
To do this I ran the following commands:
GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
GRANT USAGE ON SCHEMA public TO testuser;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO testuser;
testuser now has access to all tables in the database, but if I try to run SELECT * FROM testview I get the following error: permission denied for relation testview.
What is wrong? How do testuser get access to testview?
I agree it should work. With permissions GRANT ... ON ALL TABLES should include views too.
Did you create the view after granting the privileges to testuser? If so then it doesn't have the same privileges as the other tables. That's because GRANT ... ON ALL TABLES means "on all tables that currently exist". To include tables/views you create in the future, you can say:
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO testuser;
Or if you want to give more than SELECT, you can say ALL PRIVILEGES instead.
I think this behavior of ON ALL TABLES is one of the most misunderstood bits about Postgres permissions, and it isn't really called out in the standard documentation, so I tried to emphasize it in my own Postgres permissions overview.
postgres=# GRANT ALL PRIVILEGES ON DATABASE testdb TO testuser;
postgres=# GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO testuser;
GRANT USAGE on schema:
GRANT USAGE ON SCHEMA schema_name TO username;
Grant SELECT for a specific table:
GRANT SELECT ON tbl_loans_new TO oloffm;
Grant SELECT for multiple tables:
GRANT SELECT ON ALL TABLES IN SCHEMA schema_name TO username;