Apps built with AI builders Required
Turn on row-level security for every table
When the browser talks to the database directly, turn on row-level security for every table and write a policy for each action.
How to do it
Builders often pair the app with a hosted database, such as Supabase, that the browser can query with a public key. That key is public by design, so only the database policies stand between strangers and your data. Write policies that compare the row's owner with the signed-in user. Insert and update policies need a with check clause too, or users can write rows for someone else. Do the same for file storage buckets.
Example
alter table orders enable row level security;
create policy "owners read their orders" on orders
for select to authenticated
using ((select auth.uid()) = customer_id);
create policy "owners add their orders" on orders
for insert to authenticated
with check ((select auth.uid()) = customer_id);
-- Check: must return no rows
select tablename from pg_tables where schemaname = 'public' and not rowsecurity;
How to check
A query lists public tables without row-level security, and it returns no rows. Using only the public key, read each table signed out, then as another user. Both return nothing.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers ai development playbook: https://agentwranglers.se/playbook/ai-assisted-development/apps-built-with-ai-builders/row-level-security.