Guide Supabase

Railway leak: which Supabase keys to rotate, and in what order

Short answer

Railway says someone may have read the private settings stored in your Railway project, like passwords and keys, and decrypted some of them. Railway asks you to replace all of them. For a Supabase app, that means: make new Supabase keys, put them in your app and redeploy, turn off the old keys, then replace your database password. Expect a short outage on the database step.

Before you start

Railway build status (checked Oct 22, 2026, 2:08 PM PT): builds were already back for Pro and Enterprise, and are now back for Hobby workspaces, but deployments may take longer than usual. Free and Trial workspaces are still waiting; Railway says it will turn their builds on once Hobby is stable. On those plans you may not be able to roll out new versions yet. You can still prepare each step. Check Railway's status page for the latest.

  • Each step only takes effect once your services are redeployed.
  • The order below is our judgment. Railway hasn't published a priority order.

The order

  1. Make new Supabase keys. In your Supabase dashboard, under Settings, then API Keys, create the new keys: a secret key (it starts with sb_secret_) and a publishable key (it starts with sb_publishable_). The old admin key (the legacy service_role key) can't be reissued on its own, so you swap it for the new secret key. Creating the new keys doesn't break anything. Your old keys keep working until you turn them off.
  2. Swap them in and redeploy. In your Railway settings, replace the old admin key with the new secret key. In the code that runs in your users' browsers (your frontend), replace the legacy anon key with the new publishable key, which has the same low access. Then redeploy each service that uses them.
  3. Turn off the old keys. Deactivate the legacy keys in Supabase. Creating new keys doesn't turn off the old ones, so this step is what cuts off a leaked copy. Heads up: turning off the legacy keys also turns off the public key your app uses (the legacy anon key). Only do this after step 2 is live everywhere. Use the "last used" indicators on the API Keys page to confirm nothing still uses the old keys. Turning the legacy keys off can be undone.
  4. Was your JWT secret stored in Railway too? (That's the secret that signs your users' logins.) If yes, swapping keys isn't enough. Move to JWT signing keys (Supabase's newer way to sign logins) and rotate to a new key. First make sure nothing in your app checks logins against the old JWT secret directly, or it will break. Rotating doesn't sign anyone out by itself. Revoking the old secret does sign out anyone whose login hasn't expired yet, and during an incident you may want to revoke it right away. You have to turn off the legacy anon and service_role keys (step 3) before you can revoke it.
  5. Replace the database password. In Railway, use Regenerate on the database. Railway's advice is to regenerate first and accept a short outage, because cutting off the old password matters more. The old password stops working right away, so your app can't reach the database until each service is redeployed.
  6. Redeploy and fix pasted connection strings. Services that use Railway's reference value (${{ Postgres.DATABASE_URL }}) pick up the new password on redeploy. Services with a pasted connection string, and anything using DATABASE_PUBLIC_URL, need the new value pasted in by hand. Don't edit POSTGRES_PASSWORD or PGPASSWORD by hand.
  7. Replace everything else stored in Railway. Railway asks you to replace all environment variables, including any API keys and private registry credentials.

Want an outside look at your site afterwards? Run our free check for exposed keys and missing security headers.

Where we can help

Free instant check: paste your URL at patchandship.com/check.html to scan your homepage's JavaScript for secret keys and security headers (no signup, nothing stored). Paid, fixed price per app: Database Check, $49; Security Fix, $149 (every critical issue on our checklist fixed within 48 hours of working access); Fix & Deploy, $249. Otherwise a full refund if you ask within 14 days of purchase (Refund Policy). AI agents run the checks and a human engineer approves every change. Not a penetration test or a security guarantee.

FAQ

Can I just make a new service_role key?

No. The legacy service_role key can't be reissued on its own. Create a new secret key (sb_secret_), swap it in, redeploy, then deactivate the legacy keys.

Will turning off the legacy keys break my app?

It will if your frontend still uses the legacy anon key. Swap in the publishable key and redeploy first, then check the last used indicators before you deactivate.

Will my users be signed out?

Rotating to JWT signing keys doesn't sign anyone out by itself. Revoking the old JWT secret signs out anyone whose login hasn't expired yet.

Sources