We granted third-party software access to our postgresql database. After billing dispute we have now cut ties with this company but cannot delete the user. We need to delete this user soon but can't figure out how to do it. Here's some of what we're seeing when we try to do it:
prod=> drop user evil_user;
ERROR: role "evil_user" cannot be dropped because some objects depend on it
DETAIL: owner of default privileges on new relations belonging to role evil_user
prod=> reassign owned by evil_user to root;
ERROR: permission denied to reassign objects
prod=> drop role evil_user;
ERROR: role "evil_user" cannot be dropped because some objects depend on it
DETAIL: owner of default privileges on new relations belonging to role evil_user
^
prod=> REVOKE ALL ON ALL TABLES IN SCHEMA PUBLIC FROM evil_user;
REVOKE
prod=> drop role evil_user;
ERROR: role "evil_user" cannot be dropped because some objects depend on it
DETAIL: owner of default privileges on new relations belonging to role evil_user
prod=> REVOKE ALL ON SCHEMA public FROM evil_user;
REVOKE
prod=> REVOKE ALL ON DATABASE prod FROM evil_user;
REVOKE
prod=> reassign owned by evil_user to root;
ERROR: permission denied to reassign objects
prod=> drop user evil_user;
ERROR: role "evil_user" cannot be dropped because some objects depend on it
DETAIL: owner of default privileges on new relations belonging to role evil_user
^
prod=> ALTER DEFAULT PRIVILEGES IN SCHEMA public REVOKE ALL ON TABLES FROM evil_user;
ALTER DEFAULT PRIVILEGES
prod=> drop user evil_user;
ERROR: role "evil_user" cannot be dropped because some objects depend on it
DETAIL: owner of default privileges on new relations belonging to role evil_user
prod=> reassign owned by evil_user to root;
ERROR: permission denied to reassign objects
We need to get these people out of our database. For a number of reason we cannot easily move to a new Postgres instance.
There are unintuitive permission requirements when using REASSIGN without a supserusesr account, such as on RDS and Cloud SQL, but it is possible as long as your current_user has permission to GRANT evil_user TO prod. See this other post where I answered the same question: https://stackoverflow.com/a/62557497/79079
prod=> reassign owned by evil_user to root;
ERROR: permission denied to reassign objects
You must perform this action as a postgres superuser account, usually the user postgres.
Related
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?
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)
I am struggling with dropping a ready only user I created on one of the database in the cluster. I created a read only user using following script:
CREATE USER is_user_readonly WITH ENCRYPTED PASSWORD 'test1';
GRANT CONNECT ON DATABASE db1 to is_user_readonly;
GRANT USAGE ON SCHEMA public to is_user_readonly;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO is_user_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO is_user_readonly;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO is_user_readonly;
I logged in database db1 and created this user is_user_readonly. I logged in as admin. This user is created on all databases in the cluster.
Now, for dropping this user, I logged in db1 as admin and ran below scripts:
REVOKE ALL PRIVILEGES ON DATABASE db1 FROM is_user_readonly;
REVOKE ALL PRIVILEGES ON SCHEMA public FROM is_user_readonly;
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM is_user_readonly;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM is_user_readonly;
REVOKE USAGE ON SCHEMA public FROM is_user_readonly;
REVOKE CONNECT ON DATABASE db1 FROM is_user_readonly;
At this point I am really pulling out my hair that there is still some dependency.
SQL Error [2BP01]: ERROR: role "is_user_readonly" cannot be dropped because some objects depend on it
Detail: privileges for default privileges on new relations belonging to role isadmin in schema public
ERROR: role "is_user_readonly" cannot be dropped because some objects depend on it
Detail: privileges for default privileges on new relations belonging to role isadmin in schema public
ERROR: role "is_user_readonly" cannot be dropped because some objects depend on it
Detail: privileges for default privileges on new relations belonging to role isadmin in schema public.
Do I need to run the revoke script on all database in this cluster?
Any help is highly appreciated.
Revoke the default privileges:
ALTER DEFAULT PRIVILEGES FOR ROLE whatever IN SCHEMA public
REVOKE SELECT ON TABLES FROM is_user_readonly;
The role whatever here is the user you were logged in as when you ran the ALTER DEFAULT PRIVILEGES statement.
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.)
As a Superuser, I have created two roles in Postgres on the same schema:
read_only_with_create_view
read_write
Then I created two users from each role:
read_only_with_create_view_user
read_write
Now any new views created by read_only_with_create_view_user cannot be accessed by read_write_user as the owner for views is different (read_only_with_create_view_user).
So what is the way to access all new views by read_write_user?
I want everything created by one user to be accessible to another user.
Steps I followed:
CREATE ROLE read_only_role WITH
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity';
GRANT CONNECT ON DATABASE mydb to read_only_role;
GRANT USAGE,CREATE ON SCHEMA myschema TO read_only_role;
GRANT SELECT ON ALL TABLES IN SCHEMA myschema TO read_only_role;
GRANT SELECT ON ALL SEQUENCES IN SCHEMA myschema TO read_only_role;
CREATE USER read_only_with_create_view_user
WITH PASSWORD '*****'
in ROLE read_only_role;
-- Now created new views using this role. That means read_only_with_create_view_user is owner of those views.
-- Creating new read-write role.
CREATE ROLE rw_role WITH
NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION VALID UNTIL 'infinity' IN ROLE read_only_role;
GRANT CONNECT ON DATABASE mydb to rw_role;
GRANT USAGE ON SCHEMA myschema TO crn_rw_role_qa;
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA myschema TO rw_role;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA myschema TO rw_role;
CREATE USER read_write_user
WITH PASSWORD '*****'
in role rw_role;
After login with read_write_user, when I try to access new views created by read_only_with_create_view_user, I get this error:
ERROR: permission denied for relation view_name
********** Error **********
ERROR: permission denied for relation view_name
SQL state: 42501
You can set a role as a member of another role:
GRANT read_only_with_create_view_user TO read_write_user;
More info here.
EDIT
It will never work as you expect. See your current user schema:
Role read_write_user will cannot access objects owned by read_only_with_create_view_user simply because both don't have any relationship. To make this works as you expect you can reassign objects ownership to an "upper" level role, in this case: read_only_role (because everybody is a member of this role). But be warned that it will no longer be a read-only role.
You can do one of the following:
--Connected as read_only_with_create_view_user
CREATE VIEW my_view AS SELECT 1;
--Assign ownership to top-level role
ALTER VIEW my_view OWNER TO read_only_role;
Or you may prefer this approach:
--Connected as read_only_with_create_view_user
--Change current user to read_only_role
SET role = read_only_role;
--Create a view...
CREATE VIEW my_view AS SELECT 1;
--Turn back to read_only_with_create_view_user
RESET role;
If you prefer to do all at once you can reassign ownership of objects owned by read_only_with_create_view_user to your top-level role in just one command:
REASSIGN OWNED BY read_only_with_create_view_user TO read_only_role;
Finally, if you don't want to break your read-only rule you can also, of course, give permission directly to the object.
-- As read_only_with_create_view_user, execute the following:
CREATE VIEW my_view_2 AS SELECT 1;
GRANT SELECT ON my_view_2 TO read_write_user