All posts
No-Code & Tools

Supabase Is Deprecating anon and service_role Keys: How to Migrate Safely

A production-first migration guide for replacing Supabase legacy anon and service_role keys with publishable and secret keys without confusing key rotation with authorization.

Elvis Onunwa16 September 20266 min readLast updated: 16 September 2026
Supabase Is Deprecating anon and service_role Keys: How to Migrate Safely

TL;DR

  • Supabase says legacy anon and service_role keys are being deprecated by the end of 2026; migrate browser clients to publishable keys and privileged server code to secret keys.
  • Do not treat this as a find-and-replace job: inventory browser, server, Edge Function, Worker, webhook and CI usage first.
  • A publishable key is not an authorization policy; browser-accessible data still depends on correct RLS and grants.
  • Run old and new keys in parallel, verify production paths, then deactivate legacy keys only after dependencies are accounted for.
On this page⌄

If your Supabase project still uses the familiar anon and service_role API keys, this is now a migration task rather than a future cleanup idea.

Supabase’s current documentation says the legacy keys are being deprecated by the end of 2026. The replacement model uses publishable keys for public clients and secret keys for trusted backend components.

The migration itself is not difficult. The dangerous part is assuming it is only a string replacement.

A production app may use Supabase credentials in the browser, server routes, Edge Functions, Cloudflare Workers, scheduled jobs, webhooks, CI/CD, local environment files and third-party integrations. Change the wrong credential in the wrong trust boundary and you can either break production or accidentally give a public client privileged access.

The replacement map is simple

Supabase’s official migration guide maps the old keys like this:

Legacy key Replacement Typical location
anon Publishable key Browser, mobile, desktop, public clients
service_role Secret key Servers, Edge Functions, Workers, trusted backend code

See the current Supabase API key documentation and migration guide.

The important word is location. Before replacing anything, identify where each credential is actually running.

First, inventory every place your app uses Supabase

Do not start by searching only the frontend repository.

Check:

  • browser environment variables;
  • SSR/server environment variables;
  • Supabase Edge Functions;
  • Cloudflare Workers or other API layers;
  • background jobs and scheduled tasks;
  • webhook handlers;
  • CI/CD secrets;
  • deployment-platform environment variables;
  • local .env files used by developers;
  • scripts and admin utilities;
  • third-party services that call Supabase directly.

AI-built applications make this especially important because the first working version may have accumulated configuration across several tools before anyone documented the architecture.

Create a small table with credential → runtime → purpose → owner → migration status. That turns an invisible security dependency into something you can verify.

Publishable does not mean unrestricted

Supabase explicitly says its publishable key is safe to expose in a public client when Row Level Security and least-privilege access are configured correctly.

That distinction matters.

The key identifies the application component. It does not replace your authorization model.

If a browser can access a table through the Data API, your RLS policies and database grants still decide what the current user is allowed to read or change. A public key cannot rescue an unsafe policy, and hiding a public key cannot substitute for one.

If this boundary is unclear in your project, read my guide on whether the Supabase anon key is safe to expose.

Secret keys belong only on trusted backend infrastructure

Supabase’s current security guidance is unambiguous: secret and legacy service-role keys must never be exposed on the frontend because they can bypass RLS.

That means they do not belong in:

  • browser bundles;
  • public JavaScript;
  • mobile code that users can inspect;
  • public GitHub files;
  • screenshots or documentation pasted into public tickets.

Keep privileged credentials in the secret/environment-variable system of the server, Worker, Edge Function or deployment platform that needs them.

Supabase also says its newer secret-key formats can be revoked and that secret keys detected in public GitHub repositories can be automatically revoked through GitHub secret scanning. That is useful protection, but it is not a reason to become casual about credential handling.

Do not reuse one Supabase client for user and admin work

A common production mistake is creating one client and allowing its authorization context to change during a request.

Supabase’s current troubleshooting documentation notes that an SSR client initialized for privileged access can still end up using a user’s session token in its Authorization header. In that situation, requests can unexpectedly be evaluated as the user instead of bypassing RLS.

For privileged server operations, keep the admin/secret client separate from user-session clients.

That separation also makes the migration easier to reason about: one client represents the user; another represents trusted backend authority.

Migrate in parallel instead of flipping everything at once

Supabase says legacy and new key types can work simultaneously during migration.

Use that overlap.

A safer sequence is:

  1. inventory every current credential use;
  2. create or retrieve the appropriate publishable and secret keys;
  3. migrate one runtime at a time;
  4. deploy;
  5. test the real production path;
  6. inspect logs and failed requests;
  7. continue until every known dependency uses the new model;
  8. deactivate legacy keys only after verification.

Do not rotate the old keys first and then discover which forgotten webhook, Worker or admin script depended on them.

Verify business flows, not just API connectivity

A health check that can SELECT 1 does not prove your application survived the migration.

Test the flows that matter to the business:

  • sign-up and sign-in;
  • authenticated reads;
  • user-owned writes;
  • admin operations;
  • file uploads;
  • payments and payment callbacks;
  • webhooks;
  • emails triggered by backend functions;
  • scheduled jobs;
  • account deletion or other privileged operations.

For each flow, verify both the user-facing result and the resulting backend state.

A successful button click is not enough if the database write failed. A successful database write is not enough if the downstream webhook never ran.

Watch for a second Supabase change: table exposure

There is another 2026 platform change worth separating from API-key migration.

Supabase announced that new tables are no longer automatically exposed to its Data and GraphQL APIs under the newer default behaviour, with enforcement for existing projects scheduled for October 30, 2026. Projects that rely on the Data API may need explicit grants for tables created by migrations or tooling.

See the official Supabase changelog on Data API table exposure.

Do not misdiagnose a missing grant as an API-key migration failure. They affect the same access path, but they are different controls.

Treat the migration as an architecture check

The best outcome is not merely that your app uses newer strings.

You should finish knowing:

  • which components are public;
  • which components hold privileged authority;
  • where secrets are stored;
  • which tables public clients can reach;
  • what RLS protects;
  • which background integrations depend on Supabase;
  • how you can rotate credentials again without guessing.

That is a much stronger production position than “the app works.”

If an AI-built product has reached the point where credentials, RLS, deployment environments and backend authority are becoming difficult to reason about, use my AI-built app production checklist. If you need help getting the architecture production-ready, see my MVP development service or contact me.

Sources

Frequently asked questions

Questions, answered.

Is the Supabase anon key a secret?

No. Supabase's current guidance treats legacy anon keys and new publishable keys as suitable for public clients when RLS and least-privilege access are correctly configured.

What replaces the Supabase service_role key?

Supabase's current migration guidance maps legacy service_role usage to secret keys for servers, Edge Functions, Workers and other trusted backend code.

Can I expose a Supabase secret key in frontend code?

No. Supabase says secret and service-role keys bypass RLS and must never be exposed in browser or other public client code.

NEED HELP WITH THE BUILD?

Turn what you learned here into a clearer website or MVP.

Share the goal, current stage, and constraints. I’ll help you identify the smallest responsible next step.

Continue reading

Related notes.