Granting and Revoking Privileges
Ravi joined the analysts group yesterday, yet his first query fails with permission denied for schema billing. The group was granted SELECT on the tables. What is missing? PostgreSQL checks privileges at every layer of the object tree, and a grant at one layer does nothing if an outer door is shut.
The rule
Open every door on the path: database, schema, then object.
To read billing.invoices, a role needs:
CONNECTon the databasepedal.USAGEon the schemabilling(to find anything inside it).SELECTon the tablebilling.invoices.
GRANT CONNECT ON DATABASE pedal TO analysts;
GRANT USAGE ON SCHEMA billing TO analysts;
GRANT SELECT ON ALL TABLES IN SCHEMA billing TO analysts;The table privileges are SELECT, INSERT, UPDATE, DELETE, TRUNCATE, REFERENCES and TRIGGER (plus MAINTAIN from version 17). Schemas have USAGE and CREATE. REVOKE takes any of them away:
REVOKE DELETE ON public.rentals FROM pedal_app;Four rules explain most surprises:
- The owner of an object has every privilege on it and is the only one (apart from superusers) who can
ALTERorDROPit. PUBLICmeans every role. By default,PUBLICmay connect to any new database. Since PostgreSQL 15 it can no longer create objects in thepublicschema.ON ALL TABLES IN SCHEMAcovers only tables that exist now. Tomorrow's new table gets nothing.- Default privileges fix that. They say what future objects created by a given role will grant:
ALTER DEFAULT PRIVILEGES FOR ROLE pedal_owner IN SCHEMA billing
GRANT SELECT ON TABLES TO analysts;\dp billing.* in psql shows each table's access list, such as analysts=r/pedal_owner: analysts can read (r), granted by pedal_owner.
The shortcut
When you meet permission denied for X, read what X is. The message names the door that is shut: a database, a schema or a table. Then walk the path from the outside in.
Read the error
"permission denied for schema billing": the schema door, not the table.
The trap is fixing access with GRANT ALL. It hands over TRUNCATE and DELETE along with reading. Grant exactly the verbs the job needs.
Drills
Answer fast — trust the rule.
A role has SELECT on billing.invoices but gets permission denied for schema billing. What is missing?
You ran GRANT SELECT ON ALL TABLES IN SCHEMA public TO analysts; last week. A table created today is unreadable to them. Why?
Who can run DROP TABLE rentals without a superuser?
The app must add and read rentals but never remove them. Which grant fits?
Remember
- Open every door on the path: database, schema, then object.
- The error names the shut door; walk from the outside in.
- ON ALL TABLES is for today; default privileges are for tomorrow.
