PostgreSQL Access Privileges Decoder
PostgreSQL stores privileges as aclitem entries such as alice=arw/postgres or =r/postgres, and psql shows them in the "Access privileges" column. This tool turns them into plain English: who the grantee is, which privileges each letter stands for, which ones carry the grant option, who granted them, and what an empty or blank column means. It also writes the GRANT and REVOKE statements that rebuild the same ACL. The parser follows the PostgreSQL 14 to 18 source and runs entirely in your browser.
Do more than postgresql access privileges decoder — meet Chat2DB
Chat2DB is an AI-powered SQL client for Windows, macOS and Linux. Write SQL in natural language, format and optimize queries automatically, and manage MySQL, PostgreSQL, Oracle and 20+ other databases in one workspace.
How to use
- Run \dp table_name (or \l, \dn+, \df+, \ddp) in psql, or SELECT relacl FROM pg_class, and paste the output. A single entry such as bob=r*w/alice also works.
- Pick the PostgreSQL version. MAINTAIN (m) exists from 17, and SET (s) and ALTER SYSTEM (A) from 15. For a bare array or entry, also pick the object type and name.
- Read the result: each grantee's privileges in words, grant options, the grantor, revoked owner or PUBLIC defaults, and the SQL that recreates the ACL.
Frequently asked questions
What do the letters arwdDxtm mean in PostgreSQL?
Each letter is one privilege: a = INSERT, r = SELECT, w = UPDATE, d = DELETE, D = TRUNCATE, x = REFERENCES, t = TRIGGER and m = MAINTAIN (PostgreSQL 17+). Other objects use X = EXECUTE, U = USAGE, C = CREATE, T = TEMPORARY, c = CONNECT, s = SET and A = ALTER SYSTEM. A * after a letter means the grantee holds that privilege WITH GRANT OPTION, and the name after the slash is the role that granted it.
What does "=r/postgres" with nothing before the equals sign mean?
An empty grantee is PUBLIC, the pseudo-role that every role belongs to. So =r/postgres means postgres granted SELECT to everyone. Databases get =Tc/owner by default (TEMPORARY and CONNECT for everyone), and functions get =X/owner. Revoke these with REVOKE ... FROM PUBLIC.
Why is the Access privileges column empty in \dp?
A blank column means the ACL is NULL, so the built-in defaults apply: the owner has every privilege and PUBLIC has the type's defaults, which is nothing for tables. Once you run any GRANT or REVOKE, PostgreSQL stores an explicit list and \dp prints it. psql 17 and newer print (none) when the list exists but is empty, which means even the owner's privileges were revoked.
