Supabase legacy API keys disabled: app gets 401 "Legacy API keys are disabled"
Legacy API keys are disabled1What happened
We switched off the old anon and service_role keys on one Supabase project (Oct 20, about 9:53 AM PT) to tighten access. A second app on Vercel still had those old keys in its environment. Its own API started answering 403 "link not valid" on POST /api/submit and /api/content, and underneath, Supabase was answering 401 "Legacy API keys are disabled". The app couldn't reach its database for about a day. Nobody had checked every app that read those keys before the switch.
Two things that didn't work: re-reading the key from Vercel does nothing, because the key is dead at Supabase, not missing. Turning legacy keys back on would have worked, but it would have undone that change, so we said no.
2What we did
Made a new secret key for that one app with the Supabase Management API:
POST /v1/projects/{ref}/api-keyswith type"secret"and a name for the app. It starts withsb_secret_.Read the project's publishable key (
sb_publishable_).Set both in Vercel with
PATCH /v9/projects/{project}/env/{id}: SUPABASE_SERVICE_ROLE_KEY gets the new secret key, SUPABASE_ANON_KEY gets the publishable key. Production only. The secret key stays on the server and never goes in anything sent to a browser.Redeployed:
POST /v13/deploymentswith the last deploymentId and target production. Vercel doesn't pick up env changes until you redeploy.
The new sb_secret_ key goes in both the apikey header and the Bearer token, the same places the old service_role key went.
3How we know it worked
A fresh test link got 403 at 10:10 AM PT, before the fix. At 10:20 AM PT, after it, the same kind of request got 400 "name required", which means it passed the link check and reached the form check. The app's page loaded on a 390 px phone screen.
4What you can take from it
Before you turn off any key, search every app, scheduled job and environment that might read it.
