AI coding agents are good at scaffolding a Next.js app with Supabase Auth and a few tables. They are less reliable at locking those tables down. If Row Level Security (RLS) is missing or too loose, every signed-in user can read everyone else's rows.
Use this checklist before you put a preview or production URL in front of customers.
1. Turn RLS on for every user-facing table
In the Supabase dashboard (or a migration), confirm RLS is enabled on profiles, projects, documents, billing_customer, and any table that stores tenant data. A table with RLS off is public to the anon/authenticated roles that have GRANTs.
2. Prefer auth.uid() policies over client-side filters
Client .eq('user_id', user.id) is not security. The API still returns other rows if a policy allows it. Policies should look like:
SELECT / UPDATE / DELETE: auth.uid() = user_id (or auth.uid() = owner_id )
INSERT: WITH CHECK (auth.uid() = user_id)
3. Never expose the service role key in the browser
The service role bypasses RLS.…