allow create table for some users, not all - postgresql

I need to create 2 roles in postgres, a read only role that only has permission to run SELECT queries, and an admin role that has full superuser privileges.
How can I remove "CREATE TABLE" from 1 role, while allowing "CREATE TABLE" on another role?
I'm using "REVOKE CREATE ON SCHEMA public FROM PUBLIC" to revoke create permissions, but this applies to all roles, and I'd like to allow an admin role to still create tables.

PostgreSQL doesn't have a special CREATE TABLE privilege, everybody is always allowed to create tables. Creating tables is restricted by schema permissions: if you grant a role the CREATE privilege on a schema, that role can create tables (and other objects) in that schema.
So grant CREATE on a schema to the one role and don't grant CREATE on any schema to the other role.

Related

Snowflake revoke table/schema access

I'm trying to give an entire database access to a user, but remove access for a specific table or a specific schema that has confidential data, but it's just not working out, tried multiple - grant and revoke statements but in vain.
This is what I've tested so far.
Initially, I had this role for the user
GRANT ALL ON DATABASE raw TO ROLE transformer;
checked the grants and removed that
SHOW GRANTS TO ROLE transformer;
revoke select on all tables in schema raw.<secret_schema> from role transformer;
revoke all on DATABASE raw from ROLE transformer;
Started giving access to individual schemas/tables, but the "grant usage on database" just gives every schema/table access to the user
grant usage on database raw to role transformer ; -- usage gives all tables access
grant usage on schema raw.<open_schema> to role transformer ;
grant all on schema raw.<open_schema> to role transformer ;
grant select on all tables raw.<open_schema> to role transformer ;
Lastly, tried these revoke too, but in vain
revoke select on table raw.<secret_schema>.s from ROLE transformer;
revoke usage on schema raw.<secret_schema> from role transformer;
For more information, this access is for a DBT user and an analyst user, who can hit/select/read the raw database , but just 1 schema/table should not be accessible, rest all should be with a "future tables" clause.
Design deep-dive: https://blog.getdbt.com/how-we-configure-snowflake/
As Greg, already mentioned (and demonstrated), "GRANT ALL ON DATABASE raw TO ROLE x" does not grant permission to access the objects in the database. It grants permission to modify the database object (in your case, it's not needed and I would suggest you not grant it according to the "Principle of least privilege").
https://docs.snowflake.com/en/user-guide/security-access-control-privileges.html#database-privileges
I think, the confusing thing is, "revoke from" command does not return any error if you try to revoke permission that was not granted:
create role r2;
revoke all on database gokhan_db from role r2;
So your revoke commands do not fail, but in fact, they do not revoke anything, as this permission were assigned to the role public:
revoke select on table raw.<secret_schema>.s from ROLE transformer;
revoke usage on schema raw.<secret_schema> from role transformer;
Could you check the permissions of the role public, again?
show grants to role public;
grant usage on database raw to role transformer ; -- usage gives all
tables access
This is not what's granting access to the tables; something else is. You can confirm that running a simple script like this one:
use role securityadmin;
create role new_role_1;
grant role new_role_1 to user my_user;
use role sysadmin;
grant usage on database test to role new_role_1;
use role new_role_1;
select * from test.public.foo; --SQL compilation error: Object 'TEST.PUBLIC.FOO' does not exist or not authorized.
use role sysadmin;
select * from test.public.foo; -- Works
Roles inherit from other roles. All roles inherit from the PUBLIC role by default. Could someone have granted the PUBLIC roles the privileges that this role is inheriting? Does it inherit from a role that has more permissions than PUBLIC?

Postgres - how can I restrict the privilege to create/drop a table?

I would like to create "read-only privileges" in a PostgreSQL database (including the restriction of creating or dropping tables).
My strategy is to create a group with these privileges and then add roles that have had all their privileges revoked. In that way, the only inherit privileges when part of the read-only group.
I used the following commands to create privileges but it seems roles can add, delete tables when they join the group:
role_test_db=# REVOKE ALL ON DATABASE role_test_db FROM select_access_group;
REVOKE
role_test_db=# GRANT CONNECT ON DATABASE role_test_db TO select_access_group;
GRANT
role_test_db=# GRANT SELECT ON ALL TABLES IN SCHEMA public TO select_access_group;
GRANT
I was reading the documentation and it seems like creating tables would be under CREATE privilege but I have not granted this. Can some explain why users part of this group can still make tables?
There are several mistakes:
Revoking privileges on the database does not restrict user's rights to create objects. For that, you have to revoke privileges on the schemas.
You can only REVOKE privileges that were GRANTed (by default or explicitly). I doubt that select_access_group has ever been granted any privileges on the database.
You likely forgot to revoke the dangerous default CREATE privilege on schema public. Connect as superuser and run
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
A user can only revoke privileges that were granted directly by that user
https://www.postgresql.org/docs/13/sql-revoke.html
See privileges
\du
select * from pg_roles;
Change (base) prilileges under admin role (postgres)

Grant READ ONLY permissions to all tables in all databases

I created new role named "support" in my PostgreSQL. Now I need grant "READ ONLY" permissions for this role an ALL exists databases/tables.
Also I need automatically granted same permissions on each DB that will created in future.
I unsuccessfully tried next queries for grant permissions in new databases (Can not select from new database tables ):
ALTER DEFAULT PRIVILEGES FOR ROLE support GRANT SELECT ON TABLES TO PUBLIC;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES to support;
ALTER DEFAULT PRIVILEGES allows you to set the privileges that will be
applied to objects created in the future. (It does not affect
privileges assigned to already-existing objects.)

Creating admin user in PostgreSQL

I am trying to create an admin role/user in PostgreSQL which should fulfil the following requirements:
Should be able to do backup for the particular database (and not
others)
Should be able to create usernames which can access the
particular database (and not others).
Should be able to create/delete tables in the specific database and not other database
Should not be able to create other data bases.
This is what I have so far:
create role dba with nosuperuser createdb createrole nologin replication bypassrls;
grant usage on schema public to dba;
alter default privileges in schema public grant all on tables to dba;
alter default privileges in schema public grant all on sequences to dba;
grant connect on database myDatabase to dba;
grant usage on schema public to dba;
grant select on all tables in schema public to dba;
grant select on all sequences in schema public to dba;
grant all privileges on all tables in schema public to dba;
create user dba_user login inherit encrypted password 'password' in role dba;
Please advise how to modify the above code to fulfill the requirements.
To achieve that, perform the following modifications:
Transfer ownership of the database and all schemas and objects in it to the new user.
Give the user CREATEROLE.
Make sure to REVOKE CONNECT ON all databases FROM PUBLIC. Grant the new user the CONNECT privilege on the database in question.
Don't give the new user any permissions on other databases or objects therein.

ERROR: permission denied for schema user1_gmail_com at character 46

I need to restrict a user, access only on a particualr schema tables only.So I tried following query and login as user1_gmail_com. But I got following error when I try to browse any schema table.
My Query:
SELECT clone_schema('my_application_template_schema','user1_gmail_com');
CREATE USER user1_gmail_com WITH PASSWORD 'myloginpassword';
REVOKE ALL ON ALL TABLES IN SCHEMA user1_gmail_com FROM PUBLIC;
GRANT SELECT ON ALL TABLES IN SCHEMA user1_gmail_com TO user1_gmail_com;
SQL error:
ERROR: permission denied for schema user1_gmail_com at character 46
In statement:
SELECT COUNT(*) AS total FROM (SELECT * FROM "user1_gmail_com"."organisations_table") AS sub
Updated Working Query:
SELECT clone_schema('my_application_template_schema','user1_gmail_com');
CREATE USER user1_gmail_com WITH PASSWORD 'myloginpassword';
REVOKE ALL ON ALL TABLES IN SCHEMA user1_gmail_com FROM PUBLIC;
GRANT USAGE ON SCHEMA user1_gmail_com TO user1_gmail_com;
GRANT SELECT ON ALL TABLES IN SCHEMA user1_gmail_com TO user1_gmail_com;
You need to grant access not only to the tables in the schema, but also to the schema itself.
From the manual:
By default, users cannot access any objects in schemas they do not own. To allow that, the owner of the schema must grant the USAGE privilege on the schema.
So either make your created user the owner of the schema, or grant USAGE on the schema to this user.
This confused me. Still not sure I'm handling it correctly. Run \h grant for the syntax within psql. Here is how I managed to get my other users and groups to work as I needed:
GRANT ALL PRIVILEGES ON SCHEMA foo TO GROUP bar;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA foo TO GROUP bar;
I kept getting this error when using flyway to deploy database changes. I do some manual setup first, such as creating the database, so flyway wouldn't need those super-admin permissions.
My Fix
I had to ensure that the database user that flyway job used had ownership rights to the public schema, so that the flyway user could then assign the right to use the schema to other roles.
Additional setup Details
I am using AWS RDS (both regular and Aurora), and they don't allow super users in the databases. RDS reserves super users for use by AWS, only, so that consumers are unable to break the replication stuff that is built in. However, there's a catch-22 that you must be an owner in postgres to be able to modify it.
My solution was to create a role that acts as the owner ('owner role'), and then assign both my admin user and the flyway user to the owner role, and use ALTER scripts for each object to assign the object's owner to the owner role.
I missed the public schema, since that was auto-created when I created the database script manually. The public schema defaulted to my admin role rather than the shared owner role. So when the flyway user tried to assign public schema permissions to other roles, it didn't have the authority to do that. An error was not thrown during flyway execution, however.