Supabase October 30, 2026 change: fix '42501 permission denied' on new tables
Published · VibeCPR
public schema are no longer reachable through the Data API (supabase-js, REST, GraphQL) until you add an explicit GRANT. Existing tables keep their grants. If your app shows 42501 permission denied for table, grant the role access, enable Row Level Security, and add policies, as one unit.What is changing on October 30, 2026?
Supabase is removing the default grants that made every new table in the public schema reachable through its Data API (the auto-generated REST and GraphQL layer that supabase-js calls). According to the official Supabase changelog:
“Once the change is rolled out to your project, new tables you create in
publicschema require an explicit opt-in (via a Postgresgrant) before the Data API can see them. Existing tables are not affected in your project, they keep their current grants and stay reachable.”
The rollout timeline from that changelog:
| Date | What happens |
|---|---|
| April 28, 2026 | Opt-in toggle at project creation |
| May 30, 2026 | New behavior becomes the default for new projects (gradual rollout) |
| September 23, 2026 | Five-week notice email to project owners and admins |
| October 23, 2026 | Final notice email |
| October 30, 2026 | New behavior enforced on all existing projects |
Who is affected?
You need to act if your app talks to Supabase through supabase-js or any client library, or through /rest/v1/ or /graphql/v1, and you (or your AI tool) will create new tables after the change. Supabase specifically calls out AI coding tools, CLI scripts and Management API calls that “create tables and expect them to be reachable over the Data API on creation.”
That describes most apps built with Lovable, Bolt, v0 or Cursor: the agent writes a migration, creates a table, and wires the frontend to it in one go.
You are not affected if your app only uses a direct Postgres connection (an ORM or server with a connection string). Tables in auth, storage, realtime and custom schemas are also unaffected.
What does the error look like?
When a grant is missing, PostgREST returns this instead of data:
{
"code": "42501",
"message": "permission denied for table your_table",
"hint": "Grant the required privileges to the current role with: GRANT SELECT ON public.your_table TO anon;"
}
In the app, this usually looks like an empty list, a spinner that never ends, or a toast that says “permission denied.” It is not a bug in your code and not a Row Level Security problem: Postgres rejects the query before RLS is checked.
How do I fix 42501 permission denied?
Do these three steps together. Supabase’s changelog says to “treat these three steps as a unit”:
-- 1. Grant the privileges each role needs
grant select on public.your_table to anon; -- only if logged-out visitors should read it
grant select, insert, update, delete on public.your_table to authenticated;
grant select, insert, update, delete on public.your_table to service_role;
-- 2. Enable Row Level Security
alter table public.your_table enable row level security;
-- 3. Add the policies you need
create policy "users can read their own rows"
on public.your_table
for select
to authenticated
using (auth.uid() = user_id);
The trap: don’t “fix” it by granting everything to anon
The fastest way to make the error disappear is grant all on all tables in schema public to anon. That brings back the exact exposure Supabase is trying to prevent. If any of those tables has RLS off, anyone with your public key can read it. That’s the bug behind CVE-2025-48757, where a researcher found inadequate RLS in 170 of 1,645 Lovable apps (about 10.3%), and behind the 16,326 exposed Supabase databases UpGuard reported on October 14, 2026.
Rule of thumb: grant anon only on tables a logged-out visitor should see, and never grant on a table without enabling RLS and writing a policy in the same migration.
A prompt you can paste into Cursor, Lovable or Bolt
Supabase no longer auto-grants Data API access on new public tables (Oct 30, 2026 change).
For every table created in our migrations after today:
1. Add explicit GRANT statements: authenticated and service_role get select/insert/update/delete;
anon gets select ONLY if logged-out users must read it, otherwise no grant.
2. In the same migration: ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
3. Add policies scoped to auth.uid() for user-owned rows. Never use USING (true) for write policies.
Show me the SQL before applying it.
Can I switch early to test?
Yes. The changelog gives the SQL to opt in on an existing project now, so you find breakage before October 30 instead of after:
alter default privileges for role postgres in schema public
revoke select, insert, update, delete on tables from anon, authenticated, service_role;
alter default privileges for role postgres in schema public
revoke usage, select on sequences from anon, authenticated, service_role;
Try this on a staging project first. The changelog also documents a rollback (re-granting default privileges), and the Supabase Security Advisor lists affected tables with remediation SQL.
Checklist before October 30
- ☐ Open Security Advisor in your Supabase dashboard and review flagged tables.
- ☐ Search your migrations for
create tablewithout a matchinggrant. - ☐ Update your AI tool’s rules or system prompt to always include grant + RLS + policy.
- ☐ Make sure every table you grant to
anonhas RLS enabled and a policy you’ve read yourself. - ☐ Separately, plan your move to the new
sb_publishable_andsb_secret_keys: Supabase’s API keys docs say the legacyanonandservice_rolekeys are being deprecated by the end of 2026.
FAQ
Will my existing app break on October 30? Not for tables that already exist. They keep their grants. Breakage happens the first time a new table is created without a grant.
Does this replace Row Level Security? No. Grants decide whether a role can touch a table at all; RLS decides which rows it sees. You need both.
Why is Supabase doing this? The changelog says agents, CLI scripts and AI platforms now create tables “and many of those operations do not have a human reviewing the diff,” so access should be an explicit, reviewable decision.
Source: Supabase changelog, “Breaking Change: Tables not exposed to Data and GraphQL API automatically”. Checked October 15, 2026.