BREAKING: Railway breach exposed customer environment variables. Rotate every secret you stored in Railway
How to fix the Railway environment variable breach: rotate every secret stored in Railway variables, move funds out of any wallet key kept there, and check provider logs for use of the old keys. Railway says an intruder reached encrypted env vars and decrypted some; stolen wallet keys were drained before the notice.
Contents
If you keep API keys, database passwords or wallet keys in Railway environment variables, assume someone else may have read them and rotate every one. Railway disclosed on October 21, 2026 that an unauthorized third party may have accessed the systems that store customer environment variables, and for some of them obtained the decrypted contents. Railway says the impact may be limited to a subset of users, but it recommends that all users roll every variable, every API key and every private registry credential stored in Railway, and review logs for those services. There is no CVE and nothing to upgrade. The only fix is new secrets.
The stolen values are already being used. Security researcher Taylor Monahan reported that crypto wallet private keys kept in Railway were drained by the address 0xd9773325282874d18cb83f1fe50f14c39750b2ee: about $371,000 across 500+ transactions, 200+ victim addresses and 19+ EVM chains, with the first theft at 19:36 UTC (3:36 PM ET). Railway's public notice went up on its status page at 21:59 UTC (5:59 PM ET), more than two hours later. Railway also says it believes this is part of a series of attacks on platform companies aimed at AI inference providers, and that it asked those providers to revoke keys. By Railway's own read, AI provider keys like OpenAI, Anthropic, Grok and OpenRouter are the point of the campaign, not a side effect.
This is our operator read of Railway's security disclosure, the Railway status incident and the per-provider recovery guides Railway published overnight.
How to fix
Start with an inventory, because you cannot rotate what you forgot you stored. Railway invalidated OAuth sessions and API tokens during the response, so log in again first.
# Re-authenticate (old sessions and API tokens were invalidated)
railway login
# Dump every variable name for each service and environment you run
railway variable list --kv -s api -e production | cut -d= -f1
railway variable list --kv -s worker -e production | cut -d= -f1
# repeat for every service, every environment (staging and PR environments too)
Then rotate in this order. The order matters more than usual because Railway builds are still limited: Pro and Enterprise workspaces can redeploy, but as of Railway's 11:01 UTC (7:01 AM ET) update on October 22, Hobby, Free and Trial workspaces were still waiting for builds. Revoking a key at the provider works now even if you cannot ship the new value yet. Your app breaks for a while. An attacker spending your money does not wait for your next deploy.
- Wallet private keys and seed phrases. These cannot be rotated. Create a new wallet on a clean machine and move every asset out of the old address now, on every chain it holds funds on. The drainer Monahan tracked swept 19+ EVM chains, so an empty mainnet balance does not mean the key was skipped.
- Anything that spends money. AI provider keys (OpenAI, Anthropic, xAI Grok, OpenRouter), Stripe secret and restricted keys, AWS access keys and Google Cloud service account keys. Revoke or deactivate at the provider, create the replacement, then update the Railway variable.
- Database credentials. For Railway's PostgreSQL template, use Regenerate in the Database tab so the password changes inside Postgres and in
DATABASE_URLtogether. Railway warns against editingPOSTGRES_PASSWORDby hand. Regenerate restarts the database and drops every open session, including any an attacker has open. Railway has the same guides for MySQL, MongoDB and Redis. - Private registry and GitHub tokens. Railway removed GitHub access tokens stored as registry credentials on your services, but Railway's own guide says those tokens still work on GitHub until you revoke them. Revoke them at
github.com/settings/tokensand reconnect GitHub in Railway. - Everything else in the list. Webhook signing secrets, JWT and session secrets, SMTP passwords, third-party SaaS keys. If it was in a Railway variable, it is in scope.
Use shared variables where you can: edit once in Project Settings and every service that references it picks up the change on its next deploy. Then redeploy each service that reads the changed values. Containers read variables only at startup, so a saved variable does nothing until the service restarts.
Check whether your keys were used
Railway's disclosure tells you to review "logs for those services," but your Railway app logs mostly show what your app did, not what a stolen key did somewhere else. Check the provider side, over a window that starts no later than October 21. Railway has not said when the intruder first got in, so widen it if anything looks off.
- AI providers. In the OpenAI usage dashboard, group by API key and compare token volume and model mix against your normal traffic. For OpenRouter, call the
GET /api/v1/keyendpoint with the exposed key before you disable it. The response shows its daily, weekly and monthly usage, and that history disappears if you delete the key. Models you never call are the tell for resold or hijacked inference. - AWS. CloudTrail Event history, lookup attribute AWS access key, the exposed key ID, the exposure window. Delete anything that key created.
- Google Cloud. Cloud Audit Logs for the service account, and remove any IAM role you did not grant, in particular Service Account Token Creator on other accounts. Tokens already minted from a disabled key stay valid for up to an hour.
- GitHub. Your security log at
github.com/settings/security-log, filtered onoauth_authorization,public_keyandpersonal_access_token, plus any deploy of a commit you do not recognize. - Databases. If the database had Public Access enabled, its password worked from anywhere on the internet through Railway's TCP proxy. Turn public access off if nothing outside the project needs it, and look at connection logs for clients you do not run.
- Railway itself. Workspace admins can open Audit Logs. Entries by Railway staff member "Faraz Patankar" revoking bucket credentials are Railway's own response, not the attacker. For your app logs,
railway logs --since 2026-10-21T00:00:00Z -s apiis a start; retention depends on your plan. - Wallets. Look up your old addresses on a block explorer and check for transfers to 0xd9773325282874d18cb83f1fe50f14c39750b2ee on any EVM chain.
What Railway already reset for you
Railway rotated the S3 ACCESS_KEY_ID and SECRET_ACCESS_KEY for every storage bucket in every environment, invalidated the GitHub tokens it held for account connections, and invalidated all Railway API tokens. The old values no longer work. That has side effects you will see today:
- Services that use a bucket keep failing with
InvalidAccessKeyIdorSignatureDoesNotMatchuntil you redeploy them. If you pasted the old bucket key as a plain value instead of a${{ my-bucket.SECRET_ACCESS_KEY }}reference, replace it. - CI jobs and scripts that call Railway's Public API with an old token now fail. Create a new token.
- Local tools, CI and S3 browsers that held the old bucket keys need the new ones from
railway bucket credentials --bucket my-bucket.
A reset by Railway is not the same as a rotation by you. Railway can reset credentials it issues. It cannot revoke your OpenAI key, your Stripe key or the GitHub token you pasted into a variable.
Who is not in scope
- Secrets that never lived in Railway. If a service fetches credentials at runtime from a separate secrets manager and the only thing in Railway is a short-lived or tightly scoped token, rotate that token and the blast radius stops there. If the vault's master token sits in a Railway variable, you are in scope.
- Railway-issued bucket credentials and Railway API tokens. Railway already invalidated them. You still have to redeploy and create new tokens, but there is nothing left for you to revoke.
- Your application code and data, as far as Railway has said. The disclosure is about environment variables. Railway has not said source code, volumes or database contents were accessed. A leaked database password on a publicly reachable database is a separate problem you have to rule out yourself.
What this is not
This is not a bug in your app or a CVE you can patch; it is a breach of the platform's secret storage, and the damage happens wherever your stolen keys still work.
Not getting an email from Railway is not an all-clear yet. Railway says it will contact affected customers directly as it confirms which accounts were hit, and it still recommends that everyone rotate.
Where HOL Guard fits
HOL Guard pauses risky actions by AI coding agents on developer machines. It cannot see inside Railway or un-leak a key, so the fix here is rotation. We track sources, timeline and scope for this incident on the HOL Guard security campaign page for the Railway breach.
References
- Railway: Security Disclosure, Wednesday October 21st
- Railway status: platform outage and security notice updates
- Railway: Redeploy buckets and reconnect GitHub after the credential reset
- Railway: Rotate PostgreSQL database credentials
- Railway: Check for unexpected OpenAI usage (Anthropic, Grok and OpenRouter guides are linked from the status page)
- Railway: Check for anomalous AWS access and GCP access
- Railway: Check for anomalous GitHub access
- Taylor Monahan on the wallet drain
- The Hacker News coverage
Continue reading
All posts
BREAKING: LiteLLM 1.107.0 on PyPI and Docker latest shipped a credential stealer. Pin 1.106.2 and rotate your AI keys
How to fix the LiteLLM 1.107.0 compromise: pin litellm to 1.106.2, rebuild from a clean image, and rotate every key the host could read. All 1.107.0 wheels on PyPI and the Docker latest, main-latest and main-stable tags shipped a credential stealer that also dumps the proxy's stored provider keys.

BREAKING: GitLab CVE-2026-110264 lets attackers run code on self-managed servers with no login, even ones patched Oct 12
How to fix CVE-2026-110264: upgrade GitLab to 19.5.1, 19.4.3, 19.3.6, or the 19.2.9, 19.1.9, 19.0.10 and 18.11.13 backports. A crafted Org-mode file gives no-login code execution on self-managed GitLab, and servers patched on October 12 are exposed again.

BREAKING: GitLab critical patch fixes no-login code execution on self-managed servers (CVE-2026-97229)
How to fix CVE-2026-97229: upgrade GitLab to 19.4.2, 19.3.5 or 19.2.8. A crafted regex in CI/CD config could run code on a self-managed GitLab server with no login. GitLab.com is already patched.
