Railway env var disclosure (Oct 21): what to rotate and in what order
All of it. Railway's Oct 21 disclosure says an unauthorized party may have accessed encrypted environment variables and, for some of them, obtained the decrypted contents, and it recommends that every user "immediately roll all environment variables, including any API keys, stored in Railway, as well as any private registry credentials, and review logs for those services for unusual activity." Its Oct 22 preliminary report repeats this for every customer who signed up before Oct 21, out of an abundance of caution.
Railway did not publish an order. The one below is ours: close what is reachable from the internet, then rotate by what a stolen value can do, starting with the keys the attacker was looking for.
Updated Oct 28, 2026: how many were exposed, and signups
Railway's preliminary report puts the scale at most 1.85% of workspaces, about 100,000, with some environment variables potentially compromised. It also says Railway asked providers to reset up to all of the keys it stored, for every user, so far more than 100,000 users got revocations. Railway is contacting customers with definite impact and, separately, a larger group it considers high risk.
What that means in practice: a revocation email doesn't tell you your workspace was in the 1.85%, and no email from Railway doesn't tell you it wasn't, because Railway says it can't tell which variables were decrypted. Its advice to rotate everything stored before Oct 21 stands.
As of Railway's Oct 27 status update, new signups are still paused and there is no date for reopening them; existing accounts and services are running. Railway says it now posts one status update a day, the next around 16:00 UTC on Oct 28.
Updated Oct 27, 2026: replacement AI keys revoked in a second batch
Railway's status notice of Oct 24 says that on Oct 23, after the attacker's access had been removed (Oct 22, 03:32 UTC), AI providers asked for another batch of potentially affected keys. Railway sent that batch to OpenAI and Anthropic. Because it could not filter keys by when they were added, the batch also included newer keys, so providers may have revoked the replacement keys you created after the incident.
Railway says these revocations are precautionary: they do not mean your replacement keys were compromised, and Railway is not under a new attack.
Check every OpenAI and Anthropic key your services use now, including ones you rotated on Oct 21–22. A revoked key fails every call, so this shows up as errors in your app, not as a security alert. 200 means the key works; 401 means it was revoked:
If a key was revoked: create a replacement in the provider's dashboard, update the Railway variable, and redeploy every service that uses it. Railway says the providers that revoked keys will also contact you directly.
If your keys still work, Railway says you don't need to repeat rotations you already completed.
Fraudulent AI spend (Railway, Oct 26)
Railway's Oct 26 update to its preliminary report says it can't refund spend made with compromised API keys. Contact the AI provider first, then open a support request at station.railway.com with timestamps, prompts and other proof of the fraudulent spend, and Railway will escalate it on your behalf.
What Railway has said (Oct 21–22)
The attacker's goal, per the preliminary report, was AI provider API keys for distillation attacks. Railway names two high-risk buckets: workspaces with a very large number of environment variables, and environments with many AI vendor keys.
Railway says at most 1.85% of workspaces (about 100,000) had some environment variables potentially compromised, and that it cannot tell which specific variables were decrypted.
Railway sent potentially exposed keys to providers (it names GitHub, GitLab, Anthropic, OpenAI, OpenRouter, Stripe and others) and asked them to revoke. A revocation email from a provider does not by itself mean your key was used.
Railway itself reset the S3 credentials of every storage bucket and the GitHub tokens it held. The GitHub personal access tokens you saved as registry credentials were removed from Railway but still work on GitHub until you revoke them.
Railway user accounts were not logged into, and all Railway access tokens were revoked. Running services stayed up; builds were paused and have since been restored.
Its advice for everyone: remove public network access to databases, rotate sensitive variables and keys, check GitHub audit logs and app access, and check registry audit logs (such as Docker Hub).
An order that matches the risk
Close public database access. In each database service's Settings > Networking, turn off Public Access unless something outside the project needs it. Until you rotate, a leaked password works from anywhere through the TCP proxy. This takes a minute and needs no redeploy of your app.
AI provider keys and payment keys. OpenAI, Anthropic, OpenRouter and similar keys were the stated target; a Stripe secret key can create charges, issue refunds and read customer data. Check each provider's dashboard first: if the provider already revoked the key, your app is failing on it now, so this step is also the outage fix. For Stripe, see rotating a leaked Stripe key.
Database credentials. For Railway Postgres and Redis templates, use Regenerate in the Database tab (Config > Connection). It changes the password and updates the service variables together. Don't edit the password variable by hand or run ALTER USER / CONFIG SET requirepass yourself; that leaves the two out of sync. Then redeploy every service that uses the database.
Cloud keys. For AWS, create a second access key on the same IAM user, put it in Railway, deploy, then deactivate (not delete) the old one. Search CloudTrail event history for the old key ID in every Region, not just the ones you use.
Source control and registry tokens. Reconnect GitHub in Railway account settings; revoke the old GHCR personal access tokens on GitHub and create new ones with read:packages; review GitHub's security log, authorized OAuth apps, GitHub Apps and SSH keys for anything you didn't add.
Auth and session secrets. JWT signing secrets, session secrets, OAuth client secrets. Sessions signed with the old secret stop verifying once it changes, so expect users to sign in again; do it once, deliberately, in the same deploy as the rest.
Everything else in the variables list. Webhook signing secrets (Stripe lets you keep the old one valid for up to 24 hours), SMTP and email API keys, analytics, error tracking, storage. Bucket credentials on Railway were already reset; those services only need a redeploy.
Rotating without avoidable downtime
Containers read variables only at startup. A new value in the Variables tab does nothing until the services that use it are redeployed. Regenerating a database redeploys only the database.
Use overlap where the provider offers it: two active AWS access keys per IAM user, a Stripe key rotation with an expiry, a Stripe webhook secret with up to 24 hours of overlap. Keep the overlap as short as your deploy, because the leaked value works for all of it.
Railway's Postgres guide is explicit about the trade-off: if you suspect a leak, cutting off the old credential matters more than the short outage while services redeploy, so regenerate first. Its zero-downtime dual-role flow is for credentials you don't think were exposed.
Replace pasted connection strings with reference variables such as ${{ Postgres.DATABASE_URL }}, and shared values with project-level shared variables, so the next rotation is one edit and a redeploy.
Update the consumers Railway can't see: local .env files, CI secrets, BI tools, cron jobs on other hosts.
Then check that the old values are dead and unused
Test each old value directly. For a Stripe key, expect 401:
For Postgres, list sessions after the regenerate. The restart dropped every earlier session, so one you don't recognize connected with the new password:
SELECT pid, usename, client_addr, application_name, backend_start
FROM pg_stat_activity
WHERE datname = current_database();
Read the logs that cover the exposure window (Railway's report puts the attack between Oct 20, 13:58 and Oct 22, 03:32 UTC): provider request logs for each old key, Railway's workspace audit log for variable reads and deploys you didn't make, CloudTrail, GitHub's security log. Audit log retention depends on your plan, so export what you need now.
Ship Check Kit · $29
Rather not run it by hand?
The Ship Check Kit has your coding agent find every key that ever left the server (SC-SEC-01 for git history, SC-SEC-02 for the browser bundle) and then confirm each one is actually revoked, not just replaced (SC-SEC-03, which fails while an old value still gets anything but a 401 or 403). Three of 44 launch checks, each with the evidence and the fix.