|
| 1 | +/* |
| 2 | + * Script: sql/admin/permissions.sql |
| 3 | + * |
| 4 | + * Purpose: Provides a high-level audit of roles, their privileges, and memberships. |
| 5 | + * |
| 6 | + * Description: |
| 7 | + * This query gives a quick overview of all non-system roles in the database. |
| 8 | + * It's the first place to look when a customer reports a "permission denied" |
| 9 | + * error or when auditing for over-privileged accounts. |
| 10 | + * |
| 11 | + * Red Flags: |
| 12 | + * - `is_superuser = 't'`: Ensure only expected administrative roles have superuser status. |
| 13 | + * - `can_login = 't'` with `password_status = 'NO PASSWORD SET'`: A significant security risk. |
| 14 | + * - `can_create_roles = 't'`: This privilege can be used for privilege escalation. |
| 15 | + * - Unexpected roles in `member_of_roles`: A role may be inheriting dangerous privileges. |
| 16 | + * |
| 17 | + * Interpretation: |
| 18 | + * - `rolname`: The name of the role being audited. |
| 19 | + * - `is_superuser`, `can_create_roles`, `can_login`: Critical boolean flags indicating a role's power. |
| 20 | + * - `member_of_roles`: Shows which other roles this role inherits privileges from. |
| 21 | + * |
| 22 | + * Safety: |
| 23 | + * This script is read-only and queries standard `pg_catalog` views (`pg_roles`, |
| 24 | + * `pg_auth_members`) which are designed for fast diagnostic access. The |
| 25 | + * `statement_timeout` set by `pgtools.sh` provides a safety guarantee. |
| 26 | + */ |
| 27 | +SELECT |
| 28 | + r.rolname, |
| 29 | + r.rolsuper AS is_superuser, |
| 30 | + r.rolcreaterole AS can_create_roles, |
| 31 | + r.rolcreatedb AS can_create_databases, |
| 32 | + r.rolcanlogin AS can_login, |
| 33 | + r.rolreplication AS is_replication_role, |
| 34 | + CASE |
| 35 | + WHEN r.rolpassword IS NOT NULL THEN 'PASSWORD SET' |
| 36 | + ELSE 'NO PASSWORD SET' |
| 37 | + END AS password_status, |
| 38 | + ARRAY( |
| 39 | + SELECT g.rolname |
| 40 | + FROM pg_auth_members am |
| 41 | + JOIN pg_roles g ON am.roleid = g.oid |
| 42 | + WHERE am.member = r.oid |
| 43 | + ) AS member_of_roles |
| 44 | +FROM pg_roles r |
| 45 | +WHERE r.rolname NOT LIKE 'pg_%' -- Exclude system roles |
| 46 | +ORDER BY r.rolsuper DESC, r.rolcreaterole DESC, r.rolcanlogin DESC, r.rolname; |
0 commit comments