# 8.2 The Manager's Orders (Default Privileges) ![The Manager's Orders](assets/arch_access_default_privs.png) The biggest headache in Postgres security is the **New Ledger Problem**. In **[[Chapter 1/1.0 - The Building Blocks of Storage|Chapter 1]]**, we learned that data is stored in shipping containers called tables. When someone creates a new table (a new ledger in the Cafe), **they are the owner, and they are the ONLY person who has the key.** Even if you previously granted the waiters `SELECT ON ALL TABLES IN SCHEMA public`, that grant only applied to the tables that existed *at that exact moment*. If the Chef buys a new recipe book tomorrow, the waiters will get a "Permission Denied" error if they try to read it. **The Intuition**: Think of Default Privileges as the **Manager's personal secretary**. The secretary only knows what to do when *their specific boss* (the Creator) signs a document. They don't have instructions for what to do when a guest (a different Role) brings in a table! **The Shape of the Idea**: Default Privileges are **Personal Automation**, not **Global Gravity**. They don't pull permissions into the schema automatically; they only trigger when a specific person performs a specific action. > [!TIP] > **The Owner's Trap** > While a "Standing Order" hands out keys automatically, the **Owner** (the creator) always holds the master lock. They can come along later and `REVOKE` the keys, or even dump the entire ledger, regardless of what the standing order said. The creator is always the ultimate authority over their own work. ## The Standing Order To fix this, you don't grant privileges on the ledger. You give a **Standing Order** to the Elephant known as `ALTER DEFAULT PRIVILEGES`. ```sql ALTER DEFAULT PRIVILEGES FOR ROLE cafe_manager IN SCHEMA public GRANT SELECT ON TABLES TO cafe_waiter; ``` This tells the elephant: *"Listen closely. Every time the `cafe_manager` creates a new ledger in the public room, I want you to immediately cut a 'read' key and hand it to `cafe_waiter`."* > [!NOTE] > **Technical Secret: The Implicit Creator Gotcha** > If you don't specify `FOR ROLE`, the elephant assumes the standing order is for **you**. If you are the one running the migrations (`cafe_manager`), that's fine. But if you are logged in as a `service_role` and someone else runs the migrations, the order will never trigger! Always be explicit about who the "Creator" is. ## The Default Privilege Gotcha The most common mistake in Postgres security is misunderstanding the `FOR ROLE` clause. **Default privileges are tied to the CREATOR of the table, not the schema.** If the `postgres` superuser logs in and creates a table, the `cafe_waiter` will **not** get access! Why? Because the elephant checks his notebook and says: *"I only have a standing order to cut keys when the `cafe_manager` creates a table. Nobody told me what to do when `postgres` creates a table!"* To truly solve the New Ledger Problem, you must apply the standing order for **every** role that might create data in that room. ## Reading the Standing Orders Just like table keys are stored in `pg_class`, these Standing Orders are physically stored in the `pg_default_acl` catalog. ```sql SELECT defaclrole::regrole, defaclnamespace::regnamespace, defaclobjtype, defaclacl FROM pg_default_acl; -- Literal Output: -- defaclrole | defaclnamespace | defaclobjtype | defaclacl -- --------------+-----------------+---------------+------------------------------ -- cafe_manager | public | r | {cafe_waiter=r/cafe_manager} ## Anatomy of a Standing Order If you look closely at the `defaclacl` column, you'll see a familiar face. The physical "Permission Stamp" used in a standing order is **identical** to the `aclitem` structure we saw in **[[Chapter 8/8.1 - The Name Tags (Roles & Privileges)|8.1 The Name Tags]]**. ```text ┌──────────────────────────────────────────────────────────┐ │ Default ACL (The Standing Order) │ ├─────────────────┬──────────────────┬─────────────────────┤ │ DEF_ROLE │ PRIVILEGES │ OBJ_TYPE │ │ (The Creator) │ (Future Stamp) │ (Table/Seq/Func) │ ├─────────────────┼──────────────────┼─────────────────────┤ │ cafe_manager │ =r/cafe_man │ r │ └─────────────────┴──────────────────┴─────────────────────┘ ``` - **`defaclrole`**: This is the most important field. It identifies the **Creator**. The standing order *only* triggers when this specific Name Tag creates an object. - **`defaclenamespace`**: The room (Schema) where the order applies. - **`defaclobjtype`**: The category of object: `r` for relations (tables), `S` for sequences, `f` for functions. - **`defaclacl`**: The actual `aclitem` stamp that will be applied to every new box created by that role. Whenever you get a mysterious "Permission Denied" on a new table, always check `pg_default_acl` and ask yourself: *"Who actually created this table, and do I have a standing order for them?"* --- | ← Previous | ↑ Table of Contents | Next → | | :--- | :---: | ---: | | [[Chapter 8/8.1 - The Name Tags (Roles & Privileges)\|8.1 The Name Tags (Roles & Privileges)]] | [[Learn You a Postgres for Great Good\|Home]] | [[Chapter 8/8.3 - The VIP List (Row-Level Security)\|8.3 The VIP List (Row-Level Security)]] |