← All advisories
VV-165mediumUnsafe agent actions2026-10-23

Supabase, 30 October 2026: new public tables are no longer exposed to the Data API without an explicit GRANT

From 30 October 2026, Supabase stops granting anon, authenticated and service_role access to new tables in the public schema of existing projects. A new table won't be reachable through supabase-js, REST or GraphQL until you GRANT access explicitly. RLS still has to be on as well.

01.

What it is

Supabase changelog (published 28 April 2026): previously every new table in public got select, insert, update and delete granted to anon, authenticated and service_role through default privileges, so it was reachable over the Data API as soon as it was created, before anyone had secured it.

The new behaviour became the default for new projects on 30 May 2026. On 30 October 2026 it applies to all existing projects. Existing tables keep their current grants. Only tables created after the change need explicit grants.

Supabase's stated reason is that agents, CLI scripts and AI platforms now create tables with no human reviewing the diff. Grants and RLS are separate layers: the grant decides whether a role can touch the table at all, and RLS decides which rows it can see.

If a grant is missing, PostgREST returns error 42501 "permission denied for table …" with a hint containing the exact GRANT. Projects that only talk to Postgres over a direct connection (psql, an ORM, a server-side connection string) are not affected.

02.

How to check

  1. Do your migrations, seed scripts, or the AI tool you build with create tables in public without GRANT statements? If so, the next table created after 30 October will fail with 42501 from supabase-js.
  2. Open Security Advisor and the Data API exposure badge in the Table Editor to see which tables are currently exposed, and confirm each one has RLS and policies you meant to write.
  3. Watch your logs for code 42501 after the change. That's the missing-grant error, not an RLS denial.
03.

How to fix

  1. Treat grant + enable RLS + policies as a single step in every migration that creates a table you want the client to reach. Grant anon only what it really needs.
  2. Tables that should never be reachable from the browser need no grant now. Leave them out, and revoke access on existing ones you don't want exposed.
  3. If an AI tool creates your tables, update its rules or system prompt (or use Supabase's agent skill) so it writes the GRANT step too, and review what it grants before you ship.
  4. To switch an existing project early, run the ALTER DEFAULT PRIVILEGES revoke statements from the changelog in the SQL Editor.
-- For each NEW table the client should reach
grant select on public.your_table to anon;            -- only if it should be public
grant select, insert, update, delete on public.your_table to authenticated;
grant select, insert, update, delete on public.your_table to service_role;
alter table public.your_table enable row level security;
create policy "users read own rows" on public.your_table
  for select to authenticated using (auth.uid() = user_id);

-- Lock down an existing table that should not be on the Data API
revoke all on table public.private_table from anon, authenticated, service_role;
04.

Sources

Related on VibeVulns
More advisories for this tool
The weekly email

One email a week. Only what changed.

Every new security hole in AI coding tools, MCP servers, app builders and the stacks they generate (Next.js, Supabase, Node, PHP), each with how to check your app and the fix. No roundups of things you already read.

Free, one email a week. Read the latest issue first if you like. One-click unsubscribe in every email. We never sell or share addresses.