← Blog

Railway's environment-variable breach: what Railway confirmed, and what changes on a server you own

Railyard

October 23, 2026 · 8 min read

On October 21, 2026, Railway published a security disclosure: an unauthorized party had gained access to systems storing customer environment variables, and for some customers, had obtained the decrypted values of those variables. Railway paused all deployments platform-wide, revoked its own access tokens, and asked every customer to rotate every secret stored on the platform. This is what Railway itself confirmed, what’s still coming from secondhand reporting, and the actual architectural reason a bring-your-own-server model changes the shape of this specific risk — not all risk, the shape of this one.

What Railway itself disclosed

Railway published two documents that matter here: a same-day security disclosure on October 21, and a longer preliminary incident report a few days later. Both are still live on Railway’s own blog, and both are the primary source for everything in this section.

According to Railway’s preliminary report, the attack ran from October 20, 13:58 UTC to October 22, 03:32 UTC — the second timestamp marks when Railway confirmed the attacker no longer had access to any internal system. The first sign was mundane: a monitoring page to the on-call engineer for elevated latency. Investigation turned that into something else fast. By 14:03 UTC on the 20th, Railway’s team had identified an attempted privilege escalation in its build infrastructure and halted build pipelines. At 19:53 UTC that same day, new evidence showed the attacker could escalate access “at higher scale, across multiple parts of the Railway system, in parallel” — at that point Railway treated it as a sustained, targeted campaign rather than an isolated bug. By October 21 at 7:25 UTC, forensics showed the attacker had reached Railway’s CI environment and decrypted artifacts containing API credentials.

Railway’s own account of the attacker’s motive is specific: the report states the attacker “was attempting to obtain AI provider API keys to perform distillation attacks,” and that early evidence suggested the attacker had access to “abliterated models and substantial compute resources” that enabled unusually sophisticated exploitation of Railway’s infrastructure. Whether or not that attribution holds up as the investigation continues, it’s Railway’s own characterization, not a guess from outside reporting.

The part that reaches customers directly: the attacker accessed Railway’s internal systems and decrypted stored environment variables for a subset of customer workspaces. Railway’s own numbers, published in the preliminary report: at most 1.85% of all workspaces had some environment variables potentially compromised — about 100,000 workspaces, by Railway’s count. Railway says this number held because its systems are “built so that if one set of keys is compromised, they should not compromise the entire system” — i.e., the blast radius was contained by design, not by luck. Separately, Railway directly notified a larger (unspecified) number of workspaces it judged high-risk based on forensic analysis of what the attacker was actually targeting — mostly workspaces holding valuable AI provider keys. Individual Railway user accounts themselves were not logged into or compromised; this was about the environment variables tied to workspaces, not account takeover.

Railway’s response, in its own words: all deployments were paused platform-wide during triage (existing, already-running deployments stayed online; what stopped was new builds and new deploys going out). Railway revoked all of its own access tokens “out of an abundance of caution.” It notified partner vendors — GitHub, GitLab, and AI providers among them — so they could proactively revoke exposed credentials, completed by 09:25 UTC on October 21. Its recommended actions for every customer: rotate every environment variable and API key stored in Railway, roll private registry credentials, remove public database network access where it existed, and review GitHub/Docker registry audit logs for anything unusual. Deployments were restored gradually starting October 22, with full restoration completing later that day.

Why did Railway’s environment variables get exposed?

Based on what Railway has published, the path was: privilege escalation inside Railway’s build infrastructure, which gave the attacker a foothold in the CI environment, which held decrypted artifacts containing API credentials — and from there, access extended into the systems storing customer environment variables, letting the attacker decrypt a subset of them. The short version: one compromised internal system (build/CI) was enough to reach a different system (the encrypted secrets store) that, on its own, should have been a harder target. That chaining is the actual lesson, more than any single step in isolation.

What’s still secondhand, not Railway’s own words

A few details that have circulated widely since the disclosure did not come from Railway’s own blog, and should be read as reported, not confirmed. Blockchain researcher Taylor Monahan and several crypto-industry outlets reported that wallet private keys stored as environment variables in Railway were swept by a single address, with losses reported around $371,000 across 500+ transactions on 19+ EVM chains, and a first theft timestamped roughly two hours before Railway’s own public notice went out. Railway’s own published materials do not mention a crypto-theft dollar figure, a specific attacker wallet address, or that timing comparison — that framing comes entirely from outside researchers and the outlets covering them. It’s plausible, it lines up with the kind of workspace the attacker was reportedly prioritizing, but it isn’t something this post can verify beyond “multiple outlets reported it, Railway did not confirm or deny the specific figure in its own posts as of this writing.”

Why a BYO-server model changes the risk shape, honestly

It would be easy to write this section as “Railyard doesn’t have this problem.” That’s not accurate, and it’s worth being precise about why.

Railyard’s control plane also stores customer environment variables centrally, encrypted at rest, in its own database — using the same general approach (encryption at rest with a server-held key) that any platform storing customer secrets uses, Railway included. If Railyard’s own control-plane database and its encryption key were both compromised, the same general class of exposure Railway described is structurally possible here too. Nothing about owning the server changes that a central dashboard needs to hold your variables somewhere before it can hand them to a server — someone has to custody the secret between the moment you type it in and the moment your app reads it.

The part that does change is what happens after that: where the decrypted copy ends up living, and what an attacker has to break into to reach a live, decrypted secret that’s actually in use. In Railway’s case, the actual path the attacker took ran through build infrastructure and a CI environment that are part of Railway’s own shared, multi-tenant operating environment — the same systems that build and run everyone’s applications. A privilege-escalation bug in that shared infrastructure put the attacker in a position to reach secrets belonging to workspaces that had nothing to do with the original vulnerability. Build infra, control plane, and the compute that runs customer code all sit inside one company’s internal perimeter, so a crack in any one of them is potentially a crack in all of them.

On a BYO-server model, the control plane still has to decrypt a customer’s variables at some point — but it does so to deliver them, once, at deploy time, to a server sitting in that specific customer’s own cloud account, not to a shared compute fleet the platform operates. The decrypted, live copy of an application’s environment — the one an attacker actually wants, because it’s the one sitting in a running process’s memory — exists on infrastructure the platform’s own engineers don’t have standing access to outside that one delivery step. A bug in the platform’s own build pipeline is a real risk to the platform’s control-plane data (same as anywhere), but it doesn’t hand an attacker a shared compute environment to pivot through to reach other customers’ live, running secrets, because there isn’t one — every customer’s “live” environment is a different machine in a different account.

That’s a narrower claim than “this can’t happen,” and it should be: it’s specifically about blast radius through shared compute, not about Railyard’s encryption being cryptographically stronger than Railway’s. The honest framing is that a BYO-server model removes one specific path to the worst outcome — an attacker pivoting from a platform-side bug straight into live secrets across many unrelated customers via shared runtime infrastructure — without removing every other path, including a breach of the control plane’s own database and key material, which remains a risk any centralized dashboard carries regardless of where the compute lives.

What this means for you, regardless of platform

A few practical takeaways apply whether you’re on Railway, Railyard, or anything else that holds secrets in a dashboard:

  • Rotate anything exposed through any platform’s dashboard on a schedule, not just after a breach disclosure — static, long-lived API keys sitting in a central store are a standing liability independent of any single incident.
  • Scope credentials tightly. A database credential that can only reach one database, or an API key with the minimum permissions it needs, limits what a stolen copy is actually worth.
  • Prefer your cloud provider’s own IAM roles or short-lived credentials over static secrets where the provider supports it — this is available specifically because, on a BYO-server model, the compute is in your own account, so your own cloud’s native identity system is an option at all.
  • Ask, for any platform you use, what has to be compromised to reach a decrypted secret that’s actually in use — not just whether the database is encrypted at rest. Encryption at rest is table stakes; the real question is how many systems stand between a bug in an unrelated part of the platform and your running application’s actual secrets.

See the full comparison: Railyard vs. Railway, and the environment-variable model itself: Variables and secrets. If you’re moving off Railway specifically: Migrating from Railway.

FAQ

Why did Railway’s environment variables get exposed? Based on Railway’s own preliminary report, an attacker escalated privileges inside Railway’s build infrastructure, reached its CI environment, and from there accessed systems storing customer environment variables — decrypting a subset of them. Railway has not disclosed the specific technical vulnerability that enabled the initial escalation.

How many Railway customers were affected? Railway’s own figure is at most 1.85% of all workspaces, about 100,000, had some environment variables potentially compromised. A separate, larger, unspecified number of workspaces judged high-risk were directly notified.

Did Railway confirm the reported crypto theft? No. The roughly $371,000 figure, the specific wallet address, and the timing comparison to Railway’s public notice all come from outside blockchain researchers and crypto-focused outlets, not from Railway’s own published disclosure or preliminary report.

Does hosting on your own server make this impossible? No. A platform’s control-plane database still has to hold your secrets somewhere before deploying them, and that store is still a target regardless of architecture. What changes is that the decrypted, live copy running in your application lives on your own server rather than inside the platform’s shared compute fleet, which removes one specific path — a platform-side bug becoming a route into other customers’ live secrets — without removing every risk.

Sources

Keep your secrets on your own server.

See how Railyard handles environment variables, and what actually changes when the server is yours.

Free plan, no card, and 14 days of Pro for every new team. One flat price per team.