Blog

Product Development & Technology

Supabase After 30 October: Table Grants, RLS and the Launch Check

Supabase After 30 October: Table Grants, RLS and the Launch Check

Check every exposed table has RLS on, policies scoped to the user, explicit grants for new tables and no secret key in the app, then test as a stranger.

Check every exposed table has RLS on, policies scoped to the user, explicit grants for new tables and no secret key in the app, then test as a stranger.

7 min read
Mehmet, Vizio AI Tech Lead, leading software development, technical architecture, and digital product delivery.
Mehmet Can Duvarci
Head of Tech

Blog

Product Development & Technology

Supabase After 30 October: Table Grants, RLS and the Launch Check

Check every exposed table has RLS on, policies scoped to the user, explicit grants for new tables and no secret key in the app, then test as a stranger.

7 min read
Mehmet, Vizio AI Tech Lead, leading software development, technical architecture, and digital product delivery.
Mehmet Can Duvarci
Head of Tech
Dithered illustration of a marble hand testing the small iron doors of a wall of strongboxes in a vaulted corridor, one door standing ajar with pink light escaping from the gap.
logo of Facebook
logo of X
logo of LinkedIn
logo of Reddit
logo of Telegram
Contents
No headings found on page

To check that a Supabase app protects user data, confirm that every table the API can reach has row level security (RLS) turned on, that each policy limits rows to the signed-in user or their team, that new tables have deliberate grants, and that no secret key ships in the app. Then test it by querying as a stranger.

Picture a founder who built a client portal with an AI app builder on top of Supabase. Sign-up works, invoices show up, the demo goes well. Before launch, a friend opens the browser's developer tools, copies the project URL and the public key from the page, and asks the database for every row in the invoices table. Every customer's invoices come back. Nothing was hacked; the table simply had no rule saying who may read which row.

What is row level security in Supabase?

Row level security (RLS) is a Postgres feature that decides, row by row, which records a database role may read or change. In Supabase it is the main thing standing between your public API key and your users' data.

A Supabase app usually talks to the database straight from the browser or mobile app through the Data API, using a publishable key (the older name is the anon key). Supabase's API keys guide is clear that "Anyone can read it, so it only reaches what Row Level Security allows." Its RLS guide is blunter: "A table in an exposed schema without RLS is readable and writable by any role with a grant on it. Enable RLS on every table in an exposed schema."

A policy is a rule attached to a table, such as "a user may read an invoice only if the invoice's customer id matches their own user id." Once RLS is on, Supabase says "no data is accessible through the API when using a publishable key, until you create policies."

What changed in Supabase on 30 October 2026?

Supabase announced in April 2026 that, from 30 October 2026, new tables created in the public schema of existing projects are no longer exposed to the Data API automatically. Each new table needs an explicit Postgres grant before the API can see it. Existing tables keep their current grants.

The changelog entry says that "new tables you create in public schema require an explicit opt-in (via a Postgres grant) before the Data API can see them," and that "Existing tables are not affected in your project, they keep their current grants and stay reachable." Apps that only use a direct database connection, through an ORM or a server with a connection string, are not affected.

Two marble hands pressing a sealed charter onto the wall beside the bricked-up doorway of a new palace wing

What this means in practice

  • A new table that "doesn't work". If the app gets a "permission denied for table" error on a table created after the change, the table is missing a grant, not a policy.

  • Grants and RLS do different jobs. A grant decides whether a role can touch the table at all. RLS decides which rows that role sees. You need both: a grant so the app can reach the table, and policies so each user reaches only their own rows.

  • Don't fix the error by granting everything. Grant only the actions each role needs. A table that signed-out visitors never read should not be granted to the anon role.

The change makes exposure a decision instead of a default. It does not make old tables safe, and it does not write policies for you.

Why do AI-built Supabase apps leak data?

Most leaks come from tables that were created without RLS or with policies that allow everyone, because the app still works in a demo either way. AI app builders produce working screens quickly, and a missing rule doesn't show up until someone queries the API directly.

There is a public record of this pattern. CVE-2025-48757, published in the US National Vulnerability Database in May 2025, describes "an insufficient database Row-Level Security policy in Lovable through 2025-04-15" that allowed unauthenticated attackers "to read or write to arbitrary database tables of generated sites." The record notes that Lovable disputes it, on the grounds that each customer is responsible for protecting their own application's data. That dispute is the practical point: whoever ships the app owns the policies.

We covered the wider set of launch problems in what breaks when an AI-built app gets real users. RLS is usually the first one we check.

How do you check RLS before launch?

Run Supabase's Security Advisor, read every policy against what the table holds, look for secret keys in the client, and then try to read and write data as a signed-out stranger and as a second user. If any of those attempts succeeds where it shouldn't, you are not ready.

The launch check

  1. Run the Security Advisor. Supabase's advisors flag tables with RLS disabled in the public schema as an error ("Table publicly accessible"), along with policies that exist on tables where RLS is off and tables with RLS on but no policies.

  2. List every exposed table. For each one, note what it holds and who should see it: everyone, signed-in users, the owner only, or a team.

  3. Read each policy. Check that it filters by the user's id or team membership, and that it covers each action (read, insert, update, delete) the app uses.

  4. Check the grants. For tables created after 30 October, confirm the grants match what each role needs, and nothing more.

  5. Search the client for secret keys. Supabase's API keys guide warns that "A secret key bypasses every Row Level Security policy you have. Never put one in a browser, a shipped application, or source control." Search the built app bundle and the repository, not just the source files.

  6. Test as a stranger. With only the project URL and the publishable key, try to read and write each table. Every attempt on private data should return nothing or an error.

  7. Test as the wrong user. Sign in as user A and try to read or change user B's rows by changing ids in requests.

  8. Check stored files too. If the app keeps uploads such as invoices or ID documents in Supabase Storage, run the same stranger and wrong-user tests on reading and uploading files.

What are the most common RLS policy mistakes?

The common mistakes are policies that allow every row, policies that trust data the user can edit, and checks that cover reading but not writing. Each one looks fine in a demo and fails with a curious user.

A marble finger guiding one letter into the single tray carved with the matching name on a long sorting table
  • "Allow all" policies. A policy whose condition is simply true, often added to make an error go away, gives every signed-in user (or everyone) every row.

  • Trusting editable fields. A policy that checks a role or team stored in a profile row the user can update lets users promote themselves. Keep roles in a table users can't write to.

  • Read rules without write rules. A user who can only read their own rows may still be able to insert rows for someone else, or update the owner field, if insert and update aren't checked.

  • Sensitive columns in a public table. A profiles table that is readable by everyone may also hold emails or phone numbers. Move those columns to a private table, or use Postgres column-level privileges, which grant access to specific columns rather than the whole table.

  • Slow policies. Policies run for every candidate row. Supabase recommends wrapping auth functions in a select so the result is cached per statement, and adding "an index on every column your policies filter on."

How we approach it at Vizio AI

When we take over an app built on Supabase, the data access review comes before any new feature. We list every table and storage bucket, write down who should see what, and compare that with the policies and grants that actually exist.

Then we test as a stranger and as a second user, fix the policies and grants, move secrets server-side, and re-run the same tests so the fix can be checked again after every release. The approach is the same as in our post on whether to fix or rebuild someone else's app: find out what is really there before deciding what to change. If your app is close to launch and you aren't sure the data is protected, see how our Venture Studio works with founders on finishing a build.

Sources

FAQs.

01

Is it safe to put the Supabase publishable key in a frontend app?

Yes, that is what it is for, but only if RLS and grants are set correctly. Supabase describes the publishable key as something anyone can read, so it reaches only what your policies allow. The key itself is not a secret. The protection comes from the rules on each table, which is why a table without RLS is open to anyone holding that key.

02

Does the 30 October change mean my existing tables are now protected?

No. Supabase says existing tables keep their current grants and stay reachable. The change only stops new tables in the public schema from being exposed to the Data API automatically. Any older table without RLS, or with an overly broad policy, is in the same state it was before. Run the Security Advisor and review those tables directly.

03

Can I use the service role or secret key in a server function?

Yes. Server-side code that you control, such as an edge function or a backend job, may use a secret key for tasks that need to bypass RLS. Keep the key in the server's environment settings, never in the client bundle or the repository, and keep those functions small, with their own checks on who is calling them.

04

Do I need RLS if my app only uses a server and never calls Supabase from the browser?

If the app reaches Postgres only through a direct connection from your server, the Data API isn't the path in, and your server's own authorisation does the job. Many projects still have the Data API enabled with tables exposed, though. Either turn on RLS for those tables or stop exposing the schema, so there is no forgotten door.

05

How often should we re-check RLS after launch?

On every release that adds a table, a column with personal data, a storage bucket or a new user role, and at least once a quarter otherwise. Keep the stranger test and the second-user test as scripts you can re-run, so checking takes minutes instead of a full review, and add the Security Advisor to your release checklist.

01

Is it safe to put the Supabase publishable key in a frontend app?

Yes, that is what it is for, but only if RLS and grants are set correctly. Supabase describes the publishable key as something anyone can read, so it reaches only what your policies allow. The key itself is not a secret. The protection comes from the rules on each table, which is why a table without RLS is open to anyone holding that key.

02

Does the 30 October change mean my existing tables are now protected?

No. Supabase says existing tables keep their current grants and stay reachable. The change only stops new tables in the public schema from being exposed to the Data API automatically. Any older table without RLS, or with an overly broad policy, is in the same state it was before. Run the Security Advisor and review those tables directly.

03

Can I use the service role or secret key in a server function?

Yes. Server-side code that you control, such as an edge function or a backend job, may use a secret key for tasks that need to bypass RLS. Keep the key in the server's environment settings, never in the client bundle or the repository, and keep those functions small, with their own checks on who is calling them.

04

Do I need RLS if my app only uses a server and never calls Supabase from the browser?

If the app reaches Postgres only through a direct connection from your server, the Data API isn't the path in, and your server's own authorisation does the job. Many projects still have the Data API enabled with tables exposed, though. Either turn on RLS for those tables or stop exposing the schema, so there is no forgotten door.

05

How often should we re-check RLS after launch?

On every release that adds a table, a column with personal data, a storage bucket or a new user role, and at least once a quarter otherwise. Keep the stranger test and the second-user test as scripts you can re-run, so checking takes minutes instead of a full review, and add the Security Advisor to your release checklist.

Read more.

Dithered illustration of a marble hand testing the small iron doors of a wall of strongboxes in a vaulted corridor, one door standing ajar with pink light escaping from the gap.
Supabase After 30 October: Table Grants, RLS and the Launch Check
Mehmet Can Duvarci
7 min

Check every exposed table has RLS on, policies scoped to the user, explicit grants for new tables and no secret key in the app, then test as a stranger.

Dithered illustration of a marble hand drawing one wax-sealed scroll from a wall of pigeonholes in a dim archive, a red thread running from the scroll back to a carved lectern under a red-lit window.
Chat With Your Company Documents: When RAG Works and When It Doesn't
Umur Duman
7 min

RAG works when documents are current, text-readable and permission-tagged. It fails on stale files, scanned PDFs and questions that need counting.

Dithered illustration seen from above of a marble bust in a round room of tall mirrors, each reflection slightly different, one mirror's crack yellow.
The AI Visibility Audit: How to Check What ChatGPT, Gemini and Perplexity Say About Your Company
Can Dinlenc
7 min

An AI visibility audit runs a fixed set of buyer questions through ChatGPT, Gemini and Perplexity, records who is named and cited, and traces wrong facts to their source.

Think AI-first.
Move future-fast.

Let’s build what’s next! From product ideas and intelligent workflows to data-driven systems and scalable growth operations.

Have a product idea, AI workflow, data system, or growth challenge that needs clearer execution?

Let’s shape the right system around it.

Think AI-first.
Move future-fast.

Let’s build what’s next! From product ideas and intelligent workflows to data-driven systems and scalable growth operations.