# 8.4 The Manager's Override (Security Definers)

We have a perfectly secure Cafe. The `secrets` table is protected by a Bouncer (Row-Level Security), ensuring the `cafe_waiter` can never read the `cafe_manager`'s safe code.
But what if the Waiter *needs* to perform an auditing task that requires reading all the secrets? We don't want to make the Waiter a permanent Manager—that's too dangerous. We need to grant them **temporary, delegated authority**.
## The Magical Stamp (Security Definer)
Postgres allows functions to be defined as `SECURITY DEFINER`. This is like a **Magical Stamp** given to the Waiter by the Manager.
Normally, when you run a function (`SECURITY INVOKER`), the Elephant asks, "Who is running this?" With a `SECURITY DEFINER` function, the Elephant asks, "Who *created* this stamp?"
Let's log in as the `postgres` Superuser (the highest level Manager) and create a stamp for the Waiters.
```sql
-- Creating the Magical Stamp
CREATE OR REPLACE FUNCTION read_all_secrets() RETURNS SETOF secrets AS $
SELECT * FROM secrets;
$ LANGUAGE sql SECURITY DEFINER SET search_path = public;
-- Revoke it from the general public, and give it ONLY to the waiters
REVoke ALL ON FUNCTION read_all_secrets() FROM PUBLIC;
GRANT EXECUTE ON FUNCTION read_all_secrets() TO cafe_waiter;
```
## Using the Stamp
Now, let's watch what happens when the lowly Waiter tries to read the `secrets` table directly versus using the Magical Stamp.
```sql
SET ROLE cafe_waiter;
-- Normal Read (Bouncer blocks the view)
SELECT * FROM secrets;
-- Literal Output:
-- id | owner | secret
-- ---+-------------+--------------------------
-- 2 | cafe_waiter | The Chef burned the toast
-- Using the Stamp (Bouncer steps aside)
SELECT * FROM read_all_secrets();
-- Literal Output:
-- id | owner | secret
-- ---+--------------+---------------------------
-- 1 | cafe_manager | The safe code is 555-1234
-- 2 | cafe_waiter | The Chef burned the toast
```
When the `read_all_secrets()` function runs, the Elephant temporarily treats the Waiter as if they were the `postgres` superuser! They bypass RLS entirely. As soon as the function ends, the magic wears off, and they are a lowly Waiter again.
> [!WARNING] The `search_path` Trap
> Never hand out a Magical Stamp without explicitly setting the `search_path` (as we did with `SET search_path = public`). If you don't map out exactly what ledger the stamp applies to, a malicious Waiter could create a fake `secrets` table in their own private schema, tricking the Manager's stamp into reading the wrong data!
---
[[Chapter 8/8.3 - The VIP List (Row-Level Security)|← 8.3 - The VIP List]] | [[Chapter 8/8.0 - The Bouncers and the VIP List|↑ 8.0 - The Bouncers]] | [[Chapter 9/9.0 - The End|9.0 - The End →]]