Stolen access keys to artificial intelligence services from Railway generated an estimated $740,000 in unauthorized spending, according to an investigation published by the platform on November 10. Railway says it will cover charges that providers do not refund, although policies vary by service.
The intrusion affected the infrastructure Railway uses to build applications and store customer secrets, such as API keys and database credentials. The company estimates that the attacker managed to decrypt environment variables from at most 1.85% of workspaces—about 100,000. That figure is an upper bound, not a count of customers whose information was confirmed stolen.
The attack began on October 20, and the intruder was expelled from Railway’s systems the following day, according to the updated report. The company has not determined who operated the attacker or how it calculated the total spending of $740,000. It does say that the intruder’s queries specifically targeted AI provider credentials and that the fraudulent usage included everything from coding agent requests to tasks related to model training.
From a build machine to customer keys
Railway detected anomalous activity on October 20. The initial access, however, had occurred earlier: at 07:28 UTC, the attacker exploited a previously unknown flaw in the build infrastructure to partially escape filesystem isolation. They were able to read some files on the host virtual machine and obtain a credential used by build servers to upload images and access certain internal systems.
The credential was supposed to be used to complete build tasks, but the internal Temporal cluster—the system Railway used to coordinate some of those processes—accepted it as belonging to a trusted client. Through its APIs, the intruder queried some of the stored histories of other jobs, which could include environment variables and secrets provided during the build.
Railway’s report counts 353 build histories read between 13:50 and 15:30 UTC on October 20. It also says the attacker obtained a copy of the company’s internal monorepository: its shared codebase for deploying many of its services. The logs do not show that the attacker downloaded customer repositories.
Using Railway’s code, the attacker looked for other ways in. They found a misconfiguration in an OIDC link in one of the company’s cloud environments and exploited it at 03:26 UTC on October 21 to obtain a temporary credential for that environment. They then obtained two more internal credentials: one allowed them to read encrypted variables in a database if used from the internal network; the other was an SSH key.
The SSH key opened access to a machine that ran orchestration tasks for Railway’s fleet. It contained a longer-lived credential that could decrypt customer variables, which was needed to launch their workloads. Between 04:07 and 05:21 UTC, the attacker extracted encrypted variables from the database; between 04:42 and 05:14, and again between 06:36 and 07:15, they decrypted some of them using the key management service.
Database logs show that the queries selected variables whose names matched expressions supplied by the attacker. Railway says those searches prioritized AI provider keys and customers with many stored variables. There were also queries matching credentials for cloud services, databases, and payment services, but the investigation found no evidence of access to customer databases.
The preliminary report, published on October 22, placed the decryption after 05:27 UTC. The subsequent investigation corrected that sequence: Railway determined that it began at 04:42. It also clarified that the attacker had started creating test accounts on October 18, although those initial attempts were unsuccessful.
AI keys and tokens belonging to 1,852 users
Railway estimates that the potentially decrypted variables belonged to at most 1.85% of workspaces, approximately 100,000. The figure is based on the environments appearing in its logs, not on specific variables, which is why the company presents it as a possible upper limit. Based on its forensic analysis, it emailed the customers it considered to be at greatest risk.
The decrypted data also included linked account tokens belonging to 1,852 users, including GitHub OAuth tokens and BYOK agent keys. Railway says it reset all those tokens and notified each user. It found no logins to Railway accounts using credentials stolen during the incident.
The company disabled the credential that allowed variables to be decrypted. According to Railway, data the intruder may have copied in encrypted form but not decrypted can no longer be recovered using that credential. It also asked several providers to revoke potentially exposed keys before it could determine which ones had been affected. As a precaution, it shared with some providers all the keys for their services that it had stored, a measure that generated reset requests for more than 100,000 users. Therefore, receiving a revocation notice does not by itself prove that a specific key was exposed.
Railway believes the stolen credentials were used for services that resell or distribute access to models for use in distillation. Examples of fraudulent usage reported by customers include coding agent requests, evaluations of agent behavior, and checks of training tasks and their scoring systems. The company has not determined whether the original attacker operated those services or handed the keys to third parties.
“This was not a single breach followed by a single fix. The attacker probed many potential routes, in parallel, with Railway similarly hardening the routes in parallel.”
— Railway
Railway describes the response as a race involving the speed of agents and, citing Wiz, says the attacker used modified AI models to remove their restrictions and a runtime environment similar to ARTEX. It did not publish indicators of compromise, saying it is sharing them privately and expects to make them public when authorities allow it.
The company places the incident within a series of attacks against development platforms that store AI keys. In its “Black October” analysis, Wiz listed incidents disclosed during October by at least nine AI development platforms. BleepingComputer also cited attacks against Northflank, OpenCode, Warp, and Lightning AI. Railway linked its incident to cases reported between October 6 and 23, but noted that no common vulnerability or software dependency connects the attacks.
Who handles refunds
The final cost for each customer depends on the provider that processed the usage. AWS Bedrock and Google Gemini have fraud refund policies, and their teams had already begun processing refunds, according to Railway. OpenAI and SpaceXSI review claims on a case-by-case basis. For OpenAI, the customer must submit a claim and then send its case number to Railway’s support team; requests related to SpaceXSI are submitted to that same team.
Discussions with Anthropic were still ongoing when Railway published the report, so the platform said it would cover charges from affected Anthropic keys in the meantime. OpenRouter’s terms include a no-refund policy; Railway committed to covering all OpenRouter costs related to the intrusion. The company asks users to report unrecognized charges through its claims form and says it can escalate requests with providers.
The commitment to cover amounts that providers reject contrasts with the initial message Railway sent on October 26: at the time, it said it could not directly refund spending made with compromised keys and asked customers to contact providers first. The company has not published a cap on its coverage or a deadline for submitting claims. It has also not specified whether customers must pay disputed charges while each case is being reviewed.
The $740,000 figure is presented as an estimate of unauthorized usage. Railway has not explained in the report what method it used to calculate it or what period it covers. The figure refers to usage charged to the stolen keys, not an amount confirmed as refunded.
Builds paused and systems strengthened
The intrusion did not shut down applications that were already running, but Railway halted new builds twice: at 17:03 UTC on October 20 and at 07:22 UTC the following day. The disruption affected new builds and deployments; during the response, the dashboard, API, command-line interface, and support tools were also unavailable for periods.
Railway disabled internal credentials and sessions, and restored builds for all plans on October 22 at 22:49 UTC after strengthening the infrastructure. The company said it completely expelled the attacker on October 21 at 09:24 UTC; the report says that from 09:25 onward, the attacker no longer had access to customer data. These timestamps describe distinct moments in the response: the expulsion and the subsequent validation that no access remained.
The platform also changed its build system. Previously, multiple builds could run in isolation from one another on the same virtual machine. The new design assigns each build a short-lived virtual machine, in addition to the existing isolation, and limits each job’s credential to uploading a specific image. Railway says its own hardening team managed to build a second exploit by modifying the original attack less than an hour after the patch was applied. That test accelerated the migration of all users to the new system.
Railway says it closed all the weaknesses used, rotated credentials, and rebuilt internal tools from validated code. It also filed a report with the FBI’s IC3 and is working with a specialist forensic firm; the investigation is ongoing. The company expects to publish indicators of compromise when law enforcement authorizes it.
For customers, Railway recommends revoking and replacing sensitive variables stored before October 21. The charges process does not invalidate a key: it must be revoked or rotated directly with the provider that issued it. The company also advises removing public access to databases and reviewing audit logs from GitHub and container registries such as Docker Hub.
Sources: The Hacker News, BleepingComputer, Railway Blog, Railway Blog, TechCrunch, iTnews