PostgreSQL Users, Roles and Permissions: GRANT, REVOKE & CREATE ROLE
Learn PostgreSQL's role-based access system — creating roles/users, granting and revoking privileges on tables, and following the principle of least privilege.
Users, Roles and Permissions in PostgreSQL
PostgreSQL doesn't distinguish "users" from "roles" internally — a user is just a role with login permission. Roles can also represent groups of permissions that get assigned to other roles.
Creating a Role / User
CREATE ROLE app_user WITH LOGIN PASSWORD 'secret123';
-- can log in, since LOGIN is specified
CREATE ROLE readonly_group;
-- a group role — no LOGIN, so it can't connect on its own
CREATE USER is just shorthand for CREATE ROLE ... WITH LOGIN.
Granting Privileges
GRANT SELECT ON employees TO app_user;
GRANT SELECT, INSERT, UPDATE ON employees TO app_user;
GRANT ALL PRIVILEGES ON employees TO app_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO readonly_group;
Adding a User to a Group Role
GRANT readonly_group TO app_user;
-- app_user now inherits every privilege readonly_group has
Revoking Privileges
REVOKE INSERT, UPDATE ON employees FROM app_user;
REVOKE ALL PRIVILEGES ON employees FROM app_user;
Column-Level Privileges
GRANT SELECT (name, department) ON employees TO app_user;
-- app_user can read name and department, but NOT salary
Advertisement728 x 90
Listing Roles
\du
The Principle of Least Privilege
Grant only what a role genuinely needs:
- An application's database user should rarely need
DROP TABLEorCREATE ROLEprivileges. - Read-only reporting tools should only ever get
SELECT. - Reserve the
postgressuperuser role for administration, never for routine application connections.
Dropping a Role
DROP ROLE app_user;
-- fails if the role still owns objects or has active grants — revoke/reassign those first
Common Errors & Troubleshooting
ERROR: permission denied for table employees— the connecting role wasn't granted the needed privilege on that table; check with\dp employeesin psql to see current grants.- Granting a privilege but the user still can't connect — table-level grants don't help if the role lacks
CONNECTprivilege on the database itself, orLOGINif it's meant to be a real user — check both. DROP ROLEfailing with "role cannot be dropped because some objects depend on it" — the role still owns tables/other objects; either reassign ownership (REASSIGN OWNED BY old_role TO new_role;) or drop those objects first.
Key Takeaways
- In PostgreSQL, "user" and "role" are the same concept — a user is simply a role that can log in.
GRANT/REVOKEcontrol exactly which operations (SELECT,INSERT, etc.) a role can perform on which objects, down to individual columns.- Group roles let you manage permissions for many users at once, instead of granting the same privileges repeatedly.
Advertisement320 x 100