How to rotate app secrets after a platform breach (Railway, Zeabur)

For people whose app has a backend, API or worker on Railway or Zeabur. Facts checked 24 October 2026; each step ends as detected, unknown or confirmed by owner evidence.

Timothy Lindblom

Founder, Newly

Published Last updated

If your app's backend stored secrets in Railway or Zeabur, replace every one of them this week, even if no email has arrived. Create a new key at the service that issued it, put it in your host, redeploy, revoke the old key, then read that service's logs. Both platforms published their own breach reports in October 2026, and neither had a final scope at our check.

Do I need to rotate if my app used Railway or Zeabur?

A mobile app built with React Native and Expo usually talks to a backend: an API, a worker, a database. If that backend ran on either platform, the variables you gave it (database passwords, payment keys, AI provider keys, session secrets) sat in the platform's store. The app on the phone is not the problem here. The copies of your keys are.

Facts below come from each vendor's own pages, read on 24 October 2026. They are vendor statements, not independent forensics.

PlatformWhat the vendor saysWhat it asks of youDates
RailwayAn unauthorized party may have accessed encrypted environment variables and, for some, obtained the decrypted contents. Its preliminary report says user source code access is not ruled out until the final forensic report.Roll all environment variables and private registry credentials, remove public database access, and review GitHub and registry audit logs.Disclosure 21 Oct 2026. API tokens invalidated 22 Oct, 04:39 UTC. Preliminary report listed on its status page 23 Oct.
ZeaburA second incident on 14 and 15 Oct 2026. The report says environment-variable records from its platform database were taken, and that how the attacker got the first credentials cannot be confirmed yet.Replace every credential in your variables, recreate access tokens, and change database passwords inside the databases.Report 19 Oct 2026, marked preliminary. Shutdown announced 17 Oct, with servers stopping 1 to 31 Dec.

Read the vendor pages yourself: Railway's disclosure, its preliminary report and Zeabur's incident report. Zeabur also announced a wind-down, a separate event from the breach.

Neither vendor had published a per-customer list at our check, so "I got no email" is unknown, not confirmed. Treat every secret stored on the platform before the dates above as exposed. This page does not repeat any victim count, because the vendors' own numbers were still moving.

If you want the longer, host-neutral version of this advice, the rotate secrets after a breach guide on red.run.cloud covers it for site owners. This page covers what is different when the thing you ship is an app.

In what order should I rotate?

Start with the keys that can lose you money or let someone act as your backend, and finish with the ones that only read. The flow for each single secret is the same:

Four steps to rotate one secret: issue a new key at the provider, replace it in the host and redeploy, revoke the old key at the provider, then read the provider logs1. IssueNew key at the provider2. ReplaceUpdate host, redeploy3. RevokeOld key at the provider4. ReadProvider logs, datedChanging the value inside Railway or Zeabur alone does not touch step 3.
One secret, four steps. The platform holds a copy; the provider decides whether the old value still works.
OrderSecretWhere the old one is revokedWhat done looks like
1Keys that sign transactions or hold fundsOn the wallet or chain side. Move the funds first; a new key does not recover anything already moved.Funds sit under a key never stored online.
2Payment keys (sk_live_, rk_live_)Stripe Dashboard, API keys page. Rotating gives a replacement at once; choose expiry "Now" for a key you think is exposed.Old key shows expired and its request log reads zero.
3AI provider keysThe provider's console. Railway says it asked providers to revoke keys, so an old key may already fail with an auth error. Still create a new one.New key in use, old key absent from the console.
4Database passwords and connection stringsInside the database itself. Zeabur says editing an environment variable does not change the password.Login with the new password works, the old one is refused.
5Backend and auth keys (Supabase secret or legacy service_role, JWT and session secrets)Supabase: create a replacement, update every use, then delete a secret key or deactivate a legacy one. A service role key skips row level security, so do this early.Dashboard shows only the new key active. Expect users to sign in again after a signing-secret change.
6Source and registry tokensGitHub settings: revoke the old token, create a new one with only the scope needed, reconnect the platform.Old token gone from GitHub; audit log reviewed.
7Platform API and access tokensRailway invalidated its API tokens on 22 Oct, and Zeabur asks you to sign in again and recreate access tokens. Create new ones for your CLI and CI.CI runs green with the new token.

Fix the cause before the key

Supabase's guidance is to fix the root cause of a leak before rotating anything, or the new key can leak the same way. Here the cause was on the platform side, so the useful check on your side is whether a second copy of the secret sits somewhere else, such as a committed file or a build log.

How do I rotate without breaking the app?

Rotation breaks things when the new value reaches only half the places that use it. Work in this sequence for each secret.

  1. Search your project for the variable name. Because you can download your code or connect your own repository, this is a plain text search across files you hold, including workers and scheduled jobs.
  2. Create the new value at the issuer. Stripe keeps both keys working for up to 7 days when you rotate in the Dashboard, which gives time to watch the old key's request log fall to zero before expiring it. If you suspect misuse, skip the grace period.
  3. Update the platform variable, or the replacement platform's, and redeploy. Railway's bucket credentials were reset for every bucket, and its reset guide says services that reference them need a redeploy.
  4. Revoke the old value. Per GitHub's remediation guide, revoking at the provider is the most important step; deleting the text from code does not stop a copy that was already taken.

What if a key is inside the app itself?

Expo writes every variable that starts with EXPO_PUBLIC_ into the bundle, and Expo's docs say not to put secrets there. EAS offers secret-visibility variables for build jobs, and the same page says anything included in client-side code should be treated as public. If a secret ever shipped that way, rotating it on the server is the first half. The second half is a new build, because installed copies keep the old value until users update.

A Supabase publishable (or legacy anon) key is meant to be public and relies on row level security. Do not rotate it out of panic; check your policies instead, as in the 15-minute app check.

Afterwards, the OWASP Secrets Management Cheat Sheet is the plain reference for keeping the next rotation short: one inventory, least privilege per key, and a rotation you can run on a bad day.

How do I tell whether a key was used?

Rotation closes the door. The logs tell you whether anyone walked through it first. Read them at the issuer, not on the platform:

  • Stripe: the request log for each key, opened from the API keys page.
  • GitHub and registries: the account audit log and app access list, which Railway's preliminary report asks you to review.
  • Cloud and AI providers: usage, billing and sign-in history from the exposure window. For Railway that is 20 October 2026 (its report puts the unauthorized activity from 20 October to early 22 October UTC); for Zeabur dedicated servers the report suggests sign-in history back to 1 September 2026.
  • Your own database: connections from addresses you do not run.

Write down what you read and the date range. A quiet log is unknown until you have confirmed the logging was on. If something looks wrong, the website incident response playbook has the next steps for a live site.

Where do you stand?

Mark each item. Everything starts as unknown. Move one to confirmed only when you hold the evidence listed under it.

Your rotation check

  • Detected: You found the problem.
  • Unknown: Not checked yet, or the check could not tell.
  • Confirmed by owner evidence: You checked and kept the proof.
  1. 1. I have a written list of every variable that was stored in the platform, with the service that issued each one.

    Evidence: an export of variable names (never values) from the platform dashboard or your repository's .env.example, each matched to an issuer.

  2. 2. Every key on that list has been replaced and the old value revoked at the service that issued it.

    Evidence: the issuer's dashboard showing the old key deleted or expired, and the new key's creation date.

  3. 3. Database passwords were changed inside each database, and connection strings were updated afterwards.

    Evidence: the statement or console action that changed the password, and a successful connection with the new one.

  4. 4. The app and every service that used a replaced value was redeployed, and no shipped build still carries an old secret.

    Evidence: a deploy log after the change, and a search of your latest bundle for the old key prefixes.

  5. 5. I read the issuers' usage logs for the exposure window and found nothing I cannot explain.

    Evidence: a dated note of which logs you read, the date range and what you saw.

0 detected5 unknown0 confirmed by owner evidence

Your answers stay in this browser tab. Nothing is saved or sent.

Frequently asked questions

My app is on the App Store. Do I need to resubmit it?

Only if a secret was compiled into the app. Values that start with EXPO_PUBLIC_ are written into the JavaScript bundle, so a key you used there is readable by anyone with the app and a new build is needed. Keys that only lived on a server are replaced on the server and need no store release.

Railway says it notified providers. Do I still need to rotate?

Yes. A provider revoking a key on its side tells you nothing about the database password, the session secret or the registry token that sat in the same variable list. Create a new key at each issuer, update the app, and keep your own record that the old one no longer works.

I only changed the variable in the dashboard. Is that enough?

No. A variable in a platform is a copy of a secret the issuer still accepts. Zeabur's report says editing an environment variable does not change a database password, so the password has to be changed inside the database. For every key, the old value must be revoked where it was issued.

How do I know if someone used a key?

Read the usage and audit logs of the service that issued it, from 20 October 2026 for Railway and from 1 September 2026 for Zeabur dedicated servers, looking for requests from places and times you do not recognise. Quiet logs are unknown, not confirmed. Logs only show what the provider recorded.

Can a scan tell me whether my secrets leaked from a platform?

No. A scan of your live site reads what it shows an outsider, such as keys in shipped files or an exposed .env. It cannot see inside a hosting platform's storage. It can tell you whether your own site gives away the same secrets without any breach.

Should I move off Railway or Zeabur?

Zeabur announced on 17 October 2026 that its dedicated servers and shared clusters stop by 31 December 2026, so a migration is on a clock. For Railway, its preliminary report appeared on 22 to 23 October 2026 and a final forensic report was still to come at our check. Your code is yours either way if you hold a copy in your own repository.

Sources

All pages read on 24 October 2026.

  1. Security disclosure, Wednesday October 21st, Railway blog
  2. Preliminary report: October 21st security incident, Railway blog
  3. Incident QH8L8B3E: platform outage and token invalidation, Railway status
  4. Redeploy buckets and reconnect GitHub after the credential reset, Railway blog
  5. October 2026 security incident, preliminary report, Zeabur blog
  6. Zeabur is shutting down, Zeabur blog
  7. Secrets Management Cheat Sheet, OWASP Cheat Sheet Series
  8. Remediating a leaked secret in your repository, GitHub docs
  9. API keys, Stripe docs
  10. Understanding API keys, Supabase docs
  11. Environment variables in Expo, Expo docs
  12. Environment variables in EAS, Expo docs

Continue Learning