Subject: Revoke Connect Privilege from Database not working

From: "Ing. Marijo Kristo" <[email-masked]>
Date: Mon, 31 Mar 2025 17:26:13 +0200

> Hello,
> 
> we are using Vault to provision temporary users which get deleted after a
> while by the same user.
> For this purpose we have created a vault_admin user.
> 
> postgres=# \du vault_admin
>            List of roles
>  Role name  |       Attributes
> -------------+------------------------
> vault_admin | Superuser, Create role
> 
> postgres=# \l "disp_db"
> 
>         List of databases
>  Name   |       Owner       | Encoding | Locale Provider |  Collate   |  
> Ctype    | ICU Locale | ICU Rules |                               Access
> privileges
> ---------+-------------------+----------+-----------------+------------+------------+------------+-----------+--------------------------------------------------------------------------------
> disp_db | app_disp_db_admin | UTF8     | libc            | en_US.utf8 |
> en_US.utf8 |            |           |
> app_disp_db_admin=CTc/app_disp_db_admin                                     
> +
>         |                   |          |                 |            |    
>       |            |           | app_disp_db=Tc/app_disp_db_admin          
>                                   +
>         |                   |          |                 |            |    
>       |            |           | pg_database_owner=CTc/app_disp_db_admin   
>                                   +
>         |                   |          |                 |            |    
>       |            |           | vault_admin=c*/app_disp_db_admin          
>                                   +
>         |                   |          |                 |            |    
>       |            |           |
> "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00"=c/vault_admin   
> +
>         |                   |          |                 |            |    
>       |            |           | app_disp_db_readonly=c/app_disp_db_admin
> 
> 
> Removing the connect privilege with the Postgres Superuser and with the
> Vault Admin user does not work.
> 
> postgres=# select current_user;
> current_user
> --------------
> postgres
> 
> postgres=# revoke connect on database "disp_db" from
> "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00";
> REVOKE
> 
> postgres=# drop user
> "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00";
> ERROR:  role "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00"
> cannot be dropped because some objects depend on it
> DETAIL:  privileges for database disp_db
> 
> Same happens when trying to revoke with the vault admin user:
> 
> disp_db=# select current_user;
> current_user
> --------------
> vault_admin
> (1 row)
> 
> disp_db=# revoke connect on database "disp_db" from
> "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00";
> REVOKE
> disp_db=# drop user
> "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00";
> ERROR:  role "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00"
> cannot be dropped because some objects depend on it
> DETAIL:  privileges for database disp_db
> 
> Does not work via PSQL nor with pgadmin.
> 
> Best Regards
> Marijo Kristo
>

---

From: Tom Lane <[email-masked]>
Date: Tue, 01 Apr 2025 10:13:49 -0400

>> "dev_oidc-m-kristo-rewe-group-at-2025_02_28T09_06_30+00:00";

REVOKE is not being as helpful as it could be here, perhaps:
it is failing to tell you that it's a no-op because there
is no such privilege.  You never granted connect on disp_db
to that user so you can't revoke it either.

The privilege that exists by default, per [1], is that
database connect privileges are granted to PUBLIC (the
pseudo-group of all users).  If that's not what you want,
you have to do

revoke connect on database "disp_db" from public;

and then grant it out again to the users who should have it.

			regards, tom lane

[1] https://www.postgresql.org/docs/current/ddl-priv.html

---

From: "David G. Johnston" <[email-masked]>
Date: Tue, 1 Apr 2025 07:15:13 -0700

> > disp_db=# select current_user;
If you include the "granted by" clause when you perform revoke everything
usually just works.

"If a superuser chooses to issue a GRANT or REVOKE command, the command is
performed as though it were issued by the owner of the affected object." [1]

The fact vault_admin is superuser overrides the fact that it is their
specific grant that is trying to be revoked.

David J.

[1] https://www.postgresql.org/docs/current/sql-revoke.html