I'm in the middle of a database server migration and I can't figure (after googling and searching here) how can I list the database privileges (or all the privileges across the server) on PostgreSQL using the psql
command line tool?
I'm on Ubuntu 11.04 and my PostgreSQL version is 8.2.x.
10 Answers 10
postgres=> \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+----------+----------+-------------+-------------+-----------------------
postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 |
template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres +
| | | | | postgres=CTc/postgres
The docs on Privileges give an explanation of how to interpret the output. For specific privileges on a table of the current database, use \z myTable
.
-
41
\z myTable
is perfect for ensuring that you've successfully granted access to someone and avoiding looking like an idiot when you say "okay does it work now? it doesn't???"ijoseph– ijoseph2018年07月17日 17:50:07 +00:00Commented Jul 17, 2018 at 17:50
You can do that by following:
SELECT grantee, privilege_type
FROM information_schema.role_table_grants
WHERE table_name='mytable'
This gives you this kind of output:
mail=# select grantee, privilege_type from information_schema.role_table_grants where table_name='aliases';
grantee | privilege_type
--------------+-----------------
mailreader | INSERT
mailreader | SELECT
mailreader | UPDATE
mailreader | DELETE
mailreader | TRUNCATE
mailreader | REFERENCES
mailreader | TRIGGER
(7 rows)
mail=#
-
1Note that (as least under Postgres 9.4) the above will not work for materialized views.Seldom 'Where's Monica' Needy– Seldom 'Where's Monica' Needy2017年04月14日 23:24:21 +00:00Commented Apr 14, 2017 at 23:24
-
Note that you may need to run these as postgres user, or else some grants may not appear (e.g.
\dp
tells you that a specific user has access to a table, but this select would not select the related grants).Jānis Elmeris– Jānis Elmeris2021年08月10日 21:05:06 +00:00Commented Aug 10, 2021 at 21:05
perhaps you mean listing users and their privileges for a database - I can't quite tell from the question:
postgres=> \du
List of roles
Role name | Attributes | Member of
-----------------+--------------+------------------------------------------------
dba | Create role | {util_user,helpdesk_user,helpdesk_admin}
helpdesk_admin | Cannot login | {helpdesk_user}
helpdesk_user | Cannot login | {helpdesk_reader}
jack | | {helpdesk_admin}
postgres | Superuser | {}
: Create role
: Create DB
-
Nope I wanted a way to list the privileges of a specific database, but I already figured it out. Owner of the database always has all privileges, right? And afterwards we can add more privileges on the database to other users/groups. Those are listed with the \l command. But very thanks anyway.pedrosanta– pedrosanta2011年08月18日 16:20:41 +00:00Commented Aug 18, 2011 at 16:20
Using psql
meta-commands:
https://www.postgresql.org/docs/current/static/app-psql.html
Going over the page with Ctrl+F gives:
\ddp [ pattern ]
Lists default access privilege settings.
\dp [ pattern ]
Lists tables, views and sequences with their associated access privileges.
\l[+] [ pattern ]
List the databases in the server and show .... access privileges.
Also mentioned above, but not found with word "privileges" on the manual page:
\du+
for roles with login and \dg+
for roles without - will have a filed "Member of"
where you find roles granted to roles.
I deliberately skip function and language privileges here, found in psql
manual as barely manipulated (and if you do use those privileges you wont come here for an advise). same for user defined types, domains and so on - using "+" after the meta-command will show you privileges if applicable.
A little extreme way to check the privileges is dropping the user in transaction, e.g.:
s=# begin; drop user x;
BEGIN
Time: 0.124 ms
ERROR: role "x" cannot be dropped because some objects depend on it
DETAIL: privileges for type "SO dT"
privileges for sequence so
privileges for schema bin
privileges for table xx
privileges for table "csTest"
privileges for table tmp_x
privileges for table s1
privileges for table test
Time: 0.211 ms
s=# rollback;
ROLLBACK
Time: 0.150 ms
When the list is longer than N, (at least in 9.3), warning with list of privileges is collapsed, but you still can find it full in logs...
-
3In v12
\du+
and\dg+
seems to return same results. I have 2 roles withNOLOGIN
option and both are listed with both commands. Checked with\?
and it gives same description for both commands so I guess the role-with-login vs user distinction is no longer available.EAmez– EAmez2021年03月18日 14:16:58 +00:00Commented Mar 18, 2021 at 14:16
Undercovers psql uses the bellow query when you issue \du
command.
SELECT r.rolname, r.rolsuper, r.rolinherit,
r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,
r.rolconnlimit, r.rolvaliduntil,
ARRAY(SELECT b.rolname
FROM pg_catalog.pg_auth_members m
JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
WHERE m.member = r.oid) as memberof
, r.rolreplication
, r.rolbypassrls
FROM pg_catalog.pg_roles r
WHERE r.rolname !~ '^pg_'
ORDER BY 1;
-
` "ERROR: column r.rolbypassrls does not exist\n\nLINE 9: , r.rolbypassrls\n\n ^\n",` unfortunately does not workribamar– ribamar2018年12月31日 15:16:43 +00:00Commented Dec 31, 2018 at 15:16
-
1source? whats the query for
\l
?milahu– milahu2021年12月14日 15:13:17 +00:00Commented Dec 14, 2021 at 15:13
This is how you can list all privileges of a role (grantee):
SELECT grantor, grantee, table_schema, table_name, privilege_type
FROM information_schema.table_privileges
WHERE grantee = 'myuser'
Will result in:
grantor | grantee | table_schema | table_name | privilege_type
----------+----------+--------------+------------+----------------
postgres | myuser | myapp | employees | INSERT
postgres | myuser | myapp | employees | SELECT
postgres | myuser | myapp | employees | UPDATE
postgres | myuser | myapp | employees | DELETE
Works in PG 10
-
1Works also in Pg 12.RicHincapie– RicHincapie2021年04月05日 22:54:35 +00:00Commented Apr 5, 2021 at 22:54
-
I wrote
GRANT SELECT ON "MyView" TO user1;
andGRANT UPDATE ("col1") ON "MyView" TO user1;
butprivilege_type
shows onlySELECT
. Why noUPDATE
? Can I see column-specific update privileges?Oleg Yablokov– Oleg Yablokov2023年10月10日 17:10:53 +00:00Commented Oct 10, 2023 at 17:10 -
1Works also in Pg 15.Eugen Konkov– Eugen Konkov2023年10月11日 17:43:13 +00:00Commented Oct 11, 2023 at 17:43
This is my query composed of multiple answers on this question:
SELECT grantee AS user, CONCAT(table_schema, '.', table_name) AS table,
CASE
WHEN COUNT(privilege_type) = 7 THEN 'ALL'
ELSE ARRAY_TO_STRING(ARRAY_AGG(privilege_type), ', ')
END AS grants
FROM information_schema.role_table_grants
GROUP BY table_name, table_schema, grantee;
This results in something like this:
+------+--------------+----------------+
| user | table | grants |
+------+--------------+----------------+
| foo | schema.table | ALL |
| bar | schema.table | SELECT, INSERT |
+------+--------------+----------------+
-
3Getting this error in pg 9.4 - ERROR: could not find array type for data type information_schema.character_dataAdam Mulla– Adam Mulla2020年11月04日 07:40:59 +00:00Commented Nov 4, 2020 at 7:40
-
gr8 job with aggregation.samshers– samshers2021年10月26日 06:33:47 +00:00Commented Oct 26, 2021 at 6:33
A (possibly obvious) additional step is become the postgres user, otherwise you may get errors about roles not existing.
sudo su - postgres
psql -l
or
psql
postgres=> \l
You can input by following:
SELECT * FROM pg_roles;
and you will get
rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolconnlimit | rolpassword | rolvaliduntil | rolbypassrls | rolconfig | oid
maybe here you will think that there are too many roles, and this time, you can use WHERE to select what role you want to see
SELECT * FROM pg_roles WHERE rolname='your role name';
In fact, you can also just input
\du
and you will see all roles you created instead of default
-
2How is this different from existing answers posted earlier?mustaccio– mustaccio2020年06月21日 14:56:21 +00:00Commented Jun 21, 2020 at 14:56
-
Here as a supplement to the previous, I think, the previous answers were missing this part or not concise enough.Ricky Xu– Ricky Xu2020年06月21日 15:09:25 +00:00Commented Jun 21, 2020 at 15:09
list database owners
select d.datname, r.rolname
from pg_catalog.pg_database d, pg_catalog.pg_roles r
where d.datdba = r.oid;
docs: pg_database and pg_roles
related: test for a specific privilege:
select has_database_privilege('dbname', 'CREATE');
docs: has_database_privilege (via)