-- View all roles with attributes and parent role using psql command /* postgres=# \du List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- app | Create DB | {} backups | Replication | {} datadog | | {mon} dba | Superuser, Create role, Create DB | {} dev | | {} devadmin | Create DB | {} mon | | {} mozdba | Superuser | {dba} postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} psql_app | | {app} repl | Cannot login, Replication | {} slave | Replication | {repl} */ -- View all roles with attributes and parent role using query /* * equivalent query for /du command, found using psql -E */ 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; /* List of roles Role name | Attributes | Member of -----------+------------------------------------------------------------+----------- app | Create DB | {} backups | Replication | {} datadog | | {mon} dba | Superuser, Create role, Create DB | {} dev | | {} devadmin | Create DB | {} mon | | {} mozdba | Superuser | {dba} postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} psql_app | | {app} repl | Cannot login, Replication | {} slave | Replication | {repl} */ -- View all roles a user/role belongs to (recursively) WITH RECURSIVE cte AS ( SELECT oid, rolname FROM pg_roles WHERE rolname = 'app_level3' UNION ALL SELECT a.roleid, pg_get_userbyid(a.roleid) FROM cte JOIN pg_auth_members a ON a.member = cte.oid ) SELECT * FROM cte; /* oid | rolname -------+------------ 16505 | app_level3 16390 | psql_app 16385 | app (3 rows) */ -- View the recursive hierarchy of all roles/users across all schemas WITH RECURSIVE cte1 as ( SELECT b.oid, b.rolname, m.roleid as parentid FROM pg_catalog.pg_auth_members m RIGHT OUTER JOIN pg_catalog.pg_roles b ON (m.member = b.oid) WHERE b.rolname !~ '^pg_' ), cte2 as ( SELECT oid, rolname, parentid, CAST(rolname AS varchar(100)) AS inheritance_map FROM cte1 WHERE parentid IS NULL UNION ALL SELECT c1.oid, c1.rolname, c1.parentid, CAST(c2.inheritance_map || '->' || c1.rolname AS varchar(100)) AS inheritance_map FROM cte1 c1 INNER JOIN cte2 c2 ON (c1.parentid = c2.oid) ) SELECT * FROM cte2; /* oid | rolname | parentid | inheritance_map -------+------------+----------+--------------------------- 16389 | repl | | repl 16386 | mon | | mon 10 | postgres | | postgres 16394 | backups | | backups 16388 | devadmin | | devadmin 16387 | dev | | dev 16384 | dba | | dba 16385 | app | | app 16393 | slave | 16389 | repl->slave 16392 | datadog | 16386 | mon->datadog 16391 | mozdba | 16384 | dba->mozdba 16390 | psql_app | 16385 | app->psql_app 16505 | app_level3 | 16390 | app->psql_app->app_level3 */ -- View object ownership for all roles SELECT relowner as userid, pg_get_userbyid(relowner) as username, CASE WHEN relkind in ('r','t' ,'f','p') THEN 'table' WHEN relkind in ('m', 'v') THEN 'view' WHEN relkind='S' THEN 'sequence' WHEN relkind='i' THEN 'index' WHEN relkind='c' THEN 'composite_type' END as type, array_agg(relname) as owned_objs FROM pg_class WHERE relnamespace IN ( SELECT oid FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname != 'information_schema' ) GROUP BY 1,2,3 ORDER BY 2; /* userid | username | type | owned_objs --------+------------+----------+-------------------------------------- 16505 | app_level3 | index | {app_table_pkey,app_table1_pkey} 16505 | app_level3 | sequence | {app_table_id_seq,app_table1_id_seq} 16505 | app_level3 | table | {app_table,app_table1} 16384 | dba | table | {tabl3} 16384 | dba | index | {tabl3_pkey} 16384 | dba | sequence | {tabl3_id_seq} (6 rows) */ /* References: * https://www.postgresql.org/docs/10/catalog-pg-class.html * http://bajis-postgres.blogspot.com/2014/01/handy-queries-of-postgresql-let-us.html * https://dba.stackexchange.com/questions/56096/how-to-get-all-roles-that-a-user-is-a-member-of-including-inherited-roles */