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

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)

Related

Can't revoke default schema privilege

pgadmin shows the default privilege for a schema was granted to an individual user and I need to revoke privilege granted from individual users.
ALTER DEFAULT PRIVILEGES IN SCHEMA a_schema
GRANT ALL ON TABLES TO a_user;
I try the following command but can't revoke the privilege.
ALTER DEFAULT PRIVILEGES IN SCHEMA a_schema
REVOKE ALL ON TABLES FROM a_user;
Can someone show me how to revoke the default privilege schema from user?

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?

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

How to create user(read-write & readonly) and admin roles for an existing postgres database?

We have an existing postgres database in production with a superuser adm that is being used to do everything. Our web application connects to the database using the same user and also the administrators(for patching/updating etc.) use the same credentials.
We have to fix this to have roles so that we can have read-write, readonly and admin roles.
We don't want our web application and admin to connect to the database as superuser.
With that being said, I have created the following sql script to make the appropriate roles.
I am not a database expert(not yet) so wanted to know the issues or better ways to solve this.
ALTER ROLE adm NOLOGIN;
CREATE role user_role NOINHERIT;
CREATE role readonlyuser_role NOINHERIT;
CREATE role admin_role CREATEDB CREATEROLE NOINHERIT;
CREATE ROLE u_service LOGIN PASSWORD '<some password>' INHERIT;
CREATE ROLE u_admin LOGIN PASSWORD '<some password>' INHERIT;
CREATE ROLE u_reader LOGIN PASSWORD '<some password>' INHERIT;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonlyuser_role;
GRANT ALL PRIVILEGES ON SCHEMA public TO admin_role;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL PROCEDURES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON ALL ROUTINES IN SCHEMA public TO user_role, admin_role;
GRANT ALL PRIVILEGES ON SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL PROCEDURES IN SCHEMA audit TO admin_role;
GRANT ALL PRIVILEGES ON ALL ROUTINES IN SCHEMA audit TO admin_role;
GRANT admin_role TO u_admin;
GRANT user_role TO u_service;
GRANT readonlyuser_role TO u_reader;
A few things to consider.
Spell out what user_role and readonlyuser_role can do
Start by revoking all privileges from both these roles, then add them back only as needed. This makes it both clearer in your intentions about what the roles should do, and safer in practice because higher privileges than intended won't accidentally sneak in.
REVOKE ALL ON SCHEMA public FROM public; --only authorized roles can do anything here.
REVOKE ALL ON SCHEMA public FROM user_role;
REVOKE ALL ON SCHEMA public FROM readonlyuser_role;
GRANT ...
The Database Owner is a local Superuser
We usually make the db owner an additional role; one who only logs in to create or alter the schema, then gracefully exits. If your admin_role does more than this, consider adding an owner_role.
Does a public role need to connect?
Consider adding
REVOKE CONNECT ON DATABASE yourdb FROM public;
This blocks the loophole where any role created on the same DB server could log into this database.
Do all this in a transaction block
Stopping privilege assignment half-way through the job can lead to all sorts of trouble, much akin to locking your keys in your car. Make the privilege assignments a single transaction where possible, so a missed semicolon doesn't lock you out.

Revoke access to postgres database for a role

I have created a separate role "newrole" and new schema "newschema" for a certain user that should only execute some stored functions. I have managed to revoke access to schema "public" for the current database.
Logged in as "newrole" I still have access to postgres database like this:
SELECT * FROM pg_user
I want to revoke all access to the postgres database and tried following that not work:
REVOKE ALL ON DATABASE postgres FROM newrole
When logged in as newrole I can still read the postgres database.
How do I revoke any access to the postgres admin database?
I have searched a long time but not found anything regarding access to the postgres admin database.
TIA,
This issue has nothing to do with database postgres. Instead, you want to manipulate the catalog of the current database. Every database has a catalog of information on all objects in schema pg_catalog, and in standards-compliant form in schema information_schema, so you should restrict access to those for the role in question and also for the public role because every role is also member of that role:
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM newrole;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM public;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM newrole;
REVOKE ALL PRIVILEGES ON SCHEMA information_schema FROM public;
However, the system does not always honour this accross-the-board restriction, the catalogs are there for a reason and provide important functions in the database. Particularly functions may still execute.
In general, you do not want to fiddle with the catalogs unless you really know what you are doing.
you should be able to run this:
select * FROM information_schema.table_privileges where grantee = 'newrole';
to display all the privileges for newrole. With that information you should be able to explicitly revoke everything other than access to 'newschema'