𝗧𝗵𝗲 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲 𝗕𝗲𝘁𝘄𝗲𝗲𝗻 𝗙𝗶𝗹𝘁𝗲𝗿𝘀 𝗮𝗻𝗱 𝗪𝗮𝗹𝗹𝘀
You are building an AI agent with access to your data. You have two choices for security. You can filter data, or you can wall it.
Filtering means your query only returns certain rows. Walling means the agent cannot reach the hidden rows at all.
These look the same until something breaks.
I recently built a system to turn 1.2 million words into a knowledge base. I used Supabase to manage the data. I wanted my AI agents to only see public content.
I used a standard Postgres view to filter the data:
CREATE VIEW public_seeds AS SELECT * FROM moments WHERE visibility = 'public' AND is_canonical = true;
This looks correct. But it has a massive flaw. By default, a Postgres view runs as the owner, not the person calling it. The view owner often has full access. This means your Row Level Security (RLS) policies do not apply to the view.
You did not build a wall. You built a filter.
If a filter fails, an AI agent will not notice. A human sees an error or wrong data. An agent just processes whatever it receives. If your filter fails, your agent will start using private data without warning.
Postgres 15 solved this with the security_invoker option.
When you set security_invoker to true, the view runs as the calling role. This forces the view to obey your RLS policies. The view becomes a structural gate.
The correct way:
CREATE VIEW public_seeds WITH (security_invoker = true) AS SELECT * FROM moments WHERE visibility = 'public' AND is_canonical = true;
Now the wall is structural. Even if a developer writes a bad query or a join, the RLS policy protects the table.
"This should not happen" relies on everything working perfectly. "This cannot happen" relies on your architecture.
When you build for AI, you must design for what cannot happen.
Three things to check in your setup:
- Ensure you are not using the service role for agents. The service role bypasses RLS entirely.
- Check your Postgres version. You need version 15 or higher for security_invoker.
- Audit your existing views. Old views do not automatically follow new RLS policies.
Optional learning community: https://t.me/GyaanSetuAi