On October 21, 2026, Railway disclosed a security incident: an unauthorized party may have accessed encrypted environment variables and, for some of them, obtained the decrypted contents. Railway paused builds and deployments, signed users out and later invalidated all API tokens, and told users to rotate all environment variables stored in Railway.
If you run anything on Railway, your API keys, database passwords and tokens are the things to deal with today. This is the checklist I’d work through, in the order I’d work through it.
Short version: revoke and reissue every secret at the provider that issued it, starting with AI, cloud and payment keys. Don’t forget your JWT/session secrets and database passwords. Check each provider’s usage and audit logs for activity you didn’t cause. If you’re on a plan that can’t redeploy yet, revoke the dangerous keys now anyway and accept a little downtime.
What Railway has confirmed so far
Everything below comes from Railway’s own disclosure and status page, as of 07:11 UTC on October 22, 2026:
- What was hit: systems that store customer environment variables. Railway says some values may have been decrypted.
- Who: not confirmed yet. Railway’s initial analysis says the impact “may be limited to a subset of users”, and it will email affected customers directly. It still recommends that every user rotate.
- Why: Railway believes it’s part of a series of attacks on platform companies aimed at compromising AI inference providers. It has asked upstream providers to revoke keys.
- What Railway did: paused builds and deployments in all regions, signed users out of OAuth sessions, invalidated all Railway API tokens, and started rotating storage bucket credentials (new ones appear in your dashboard automatically).
- Builds: restored for Enterprise and then Pro on October 22, with deployments still slow to start. Hobby is next, then Free and Trial.
- Still unknown: how the attacker got in, when, and how many accounts are affected.
Check the status page before acting on any of this. It’s moving fast.
The catch: rotating a key can take your app down
Here’s the part that makes this harder than “just rotate everything”.
When you revoke a key at OpenAI or Stripe, the old key stops working immediately. Your app is still running with the old key in its environment. To give it the new one, you update the variable and redeploy. If your plan can’t redeploy yet, the app breaks until it can.
So you have a real tradeoff on each key:
| Key type | If it leaks | My call |
|---|---|---|
| AI provider keys (OpenAI, Anthropic, OpenRouter, xAI) | Unbounded spend. Railway believes AI inference providers were the target | Revoke now, accept downtime |
| Cloud keys (AWS, GCP) | Unbounded spend, data access | Revoke now |
| Stripe secret key | Refunds, customer data, payouts | Roll now, and set the old key to expire immediately, not after an overlap |
| GitHub tokens | Source code, push access | Revoke now |
| Database password | Read and write all your data | Change as soon as you can redeploy |
| JWT / session secret | Anyone can log in as anyone | Change as soon as you can redeploy |
| Email / SMS keys (Resend, SendGrid, Twilio) | Spam sent as you, small bills | Revoke now |
| Analytics / error-tracking DSNs | Mostly noise | Low priority |
A few minutes of downtime on a side project is cheap. A leaked OpenAI key with no spend limit is not.
Step 1: List every variable you have, everywhere
You can’t rotate what you forgot exists. In the Railway dashboard, open each service’s Variables tab. From the CLI, railway variable list prints them for the linked service (run railway login first, since Railway invalidated old sessions and tokens, and railway variable list --help shows the flags in your CLI version).
Things people miss:
- Every environment. Staging and PR environments have their own variables, often with the same production keys copied in.
- Shared variables at the project level.
- Database services. The Postgres, MySQL and Redis services have their own variables (
DATABASE_URL,DATABASE_PUBLIC_URL,PGPASSWORD,REDIS_URL). - Private registry credentials for Docker images. Railway calls these out specifically. (If you’re moving a public image off Railway, InstaPods can run it directly.)
- Old projects. That prototype from March still has your real Stripe key in it.
Write the list down. Mark each key’s provider and what it can do.
Step 2: Revoke and reissue at the provider, not just in Railway
Changing the value in Railway does nothing if the old key is still valid at OpenAI. The attacker has the old value. Kill it where it was issued.
AI providers. Delete the old key and create a new one in each dashboard (OpenAI, Anthropic Console, OpenRouter, xAI, and any others). Then open the usage page and look at the last few days for spend you don’t recognise. While you’re there, set a monthly spend limit if the provider supports one. Railway believes the attacks were aimed at compromising AI inference providers, so do these first.
AWS. Deactivate the IAM access key, create a new one, then search CloudTrail for calls made with the old key ID. Railway has a specific AWS guide.
Google Cloud. Disable the service account key, create a new one, and review Cloud Audit Logs. Railway’s GCP guide walks through it.
Stripe. Roll the secret key in the Developers section. Also roll your webhook signing secret (STRIPE_WEBHOOK_SECRET): with it, someone can send your app fake “payment succeeded” events.
GitHub. Revoke personal access tokens and deploy keys that were stored as variables. If you have a GitHub OAuth app, regenerate its client secret.
OAuth client secrets. Google, GitHub, Discord sign-in: regenerate each CLIENT_SECRET.
Email and SMS. Resend, SendGrid, Postmark, Twilio. Revoke and reissue.
Step 3: The two secrets nobody remembers
Your JWT or session secret. JWT_SECRET, SESSION_SECRET, NEXTAUTH_SECRET, AUTH_SECRET, SECRET_KEY_BASE, Django’s SECRET_KEY. These aren’t API keys, so they don’t feel urgent. They are. Whoever holds one can mint a valid login token for any user in your app, including your admin account. Generate a new random value (openssl rand -base64 32) and redeploy. Everyone gets logged out once. That’s fine.
Encryption keys your app uses. If your app encrypts data with a key from an env var (n8n’s N8N_ENCRYPTION_KEY is the common one), a leak means the encrypted data can be read by whoever also gets the database. Rotating these is app-specific and can break existing data, so read your app’s docs before changing it. For n8n, see what the encryption key does.
Step 4: Change your database passwords
If your database password sits in a Railway variable, assume it’s exposed. This matters most if you enabled a public TCP proxy on the database, because then anyone with the password and the proxy address can connect from anywhere.
For Postgres, connect and run:
ALTER USER postgres WITH PASSWORD 'a-new-long-random-password';
Then update every variable that embeds the old password (DATABASE_URL, DATABASE_PUBLIC_URL, PGPASSWORD) and redeploy the services that use it. If you can’t redeploy yet, decide whether a few hours of downtime beats leaving the old password valid. If you turned on the public proxy only for a one-off job, turn it off.
Also look at the data: unexpected new admin users, changed emails on accounts, rows you didn’t write.
Step 5: Fix what Railway’s own response broke
Railway invalidated all API tokens and OAuth sessions. Expect:
- CI deploys failing. GitHub Actions or other pipelines using
RAILWAY_TOKENneed a new token. - The CLI asking you to log in again. Run
railway login. - Storage bucket credentials changed. Railway rotated them for you. Your app picks them up on its next deploy.
Step 6: Watch for a week
Most of the damage from a leaked key shows up as usage, not as an alert. For the next 7 days, check:
- AI provider usage pages, daily
- Your cloud bill and CloudTrail / Cloud Audit Logs
- Stripe events and payouts
- GitHub security log
- Your email provider’s sent volume
If Railway emails you to say your account was in the affected set, you’ve already done the work.
Should you leave Railway over this?
Maybe, maybe not. Railway has published a disclosure, status updates and follow-up guides, and one incident isn’t by itself proof that a platform is careless. Every hosting company that stores your secrets is a target, including the one I run. The defence that holds no matter where you host: limit what one leaked key can do. Spend caps on AI keys. Scoped, least-privilege cloud keys. Short-lived tokens where you can get them. Separate keys for staging and production.
Where it gets harder to stay is when you can’t ship. A day with no deploys is a day you can’t push a fix, or even the new keys you just rotated.
If you decide to move, the cleanest time is right now, because a migration is a rotation: you issue fresh keys, put them only in the new host, and revoke the old ones after cutover. I wrote up how to migrate off Railway, covering your app, your Postgres data and your env vars, without losing anything.
For what it’s worth, on InstaPods your app runs on its own Linux server you can SSH into, the env vars live in a plain .env file in your app folder that you can read and edit yourself, and the price is flat: $3/mo for a small app, $7/mo with a database included. No usage meter, no surprise bill. If you’re comparing options, here’s how InstaPods stacks up against Railway.