· via dev.to (home feed)
Supabase Oct 30 change blocks API access to new tables; bulk-grant fix can re-expose data
On October 30, 2026, Supabase stops auto-granting Data API access to new tables; the bulk-grant fix from its announcement's rollback section can re-expose tables with RLS disabled.

What changes on October 30
According to a post by Mateus Zingano on dev.to, Supabase will stop handing out table privileges to its API-facing roles on October 30, 2026. Previously, any table created in the public schema automatically received select, insert, update and delete privileges for the anon, authenticated and service_role roles. Once the change lands, a table created without an explicit GRANT will not be reachable through the Data API at all — supabase-js, PostgREST and GraphQL are all affected — no matter how the table was made: SQL editor, migration file, CLI, MCP or an AI coding assistant.
The boundaries of the change, as the post lays them out:
- Existing tables keep the grants they already have, so running applications continue to work.
- Row-level security and policies are untouched. Grants decide whether a role can touch a table at all; RLS decides which rows it can see.
- New projects have already been on the stricter default since a gradual rollout that began on May 30.
- Anything talking to the database over a direct Postgres connection — psql, an ORM, a backend using a connection string — is unaffected. Zingano attributes this point to Supabase's official announcement.
What the breakage looks like
The first table created after the cutover returns a Postgres 42501 permission-denied error instead of rows, with a hint pointing at the missing grant. Postgres rejects the query before RLS is ever evaluated, so this is the new default working as designed, not a bug in the application's policies.
Why the obvious fix is the risky one
The quickest way to make the error vanish is a single bulk statement granting all four operations on every table in public to all three roles — a line Zingano reproduces from the rollback section of Supabase's own announcement. It works, and it also hands access to tables that were never meant to be exposed. Any of those with RLS disabled becomes readable, and possibly writable, by anyone holding the project's anon key — a key that ships inside the frontend. The new default existed to stop accidental exposure; the bulk grant reinstates it. He also flags that asking an AI tool to "fix the permission error" makes this blanket statement a probable answer.
The alternative he recommends is slower but safe: grant per table, and only the operations each role actually needs.
The migration pattern he recommends
Treat the table definition, RLS enablement, policies and grants as one unit inside the same migration, so a table never exists in a partially configured state. In his worked example, an invoices table gets RLS enabled, an owner-only select policy scoped to authenticated users, and a single grant of select to authenticated. Nothing goes to anon, because signed-out visitors have no reason to read invoices.
One gotcha: when a table uses serial or bigserial rather than an identity column and the API inserts into it, the underlying sequence needs its own usage grant.
Auditing what the API can reach today
The post supplies a query against pg_class joined with has_any_column_privilege that lists every table and view in public, whether anon or authenticated can read it, and whether RLS is on. He prefers has_any_column_privilege to the usual information_schema.table_privileges because it also surfaces column-level grants: a grant restricted to specific columns does not show up as a table privilege, yet the API still serves those columns. Every row where anon can read and RLS is off marks a table anyone with the anon key can read.
Two free, MIT-licensed tools are suggested for keeping things honest over time: airlock-migrate, which reads migration files in CI and fails the build when one creates a table without enabling RLS or turns RLS off, and airlock-rls, which checks a live database for RLS-disabled tables and policies that let everyone through. A free external scanner is also mentioned for testing whether a deployed app leaks a service_role key into the browser or exposes readable tables; it reports row counts only and never reads the data itself.
Why it matters
This is one of those platform changes that is a genuine security improvement and an operational trap at the same time. Nothing breaks on October 30 itself — the pain arrives with the first new table, when the error message invites a fix that quietly undoes the protection the change was meant to provide. Teams shipping on Supabase should audit their current grants and RLS coverage before the cutover, bake per-table grants into their migration template, and put an automated check in CI so the new default's safety margin does not erode one rushed migration at a time. The broader lesson generalises beyond Supabase: grants and row-level security are separate layers, and neither substitutes for the other.
- #supabase
- #postgres
- #database
- #security
- #cloud
- #api