El 20 de octubre, una alerta despertó a un ingeniero de Railway por llamadas a la API de un registro interno que no deberían existir. Dieciséis horas después la empresa había parado dos veces los builds de sus clientes, rotado todas sus credenciales y pedido a nueve proveedores de IA que revocaran claves que aún no podía demostrar robadas.
El recuento final del informe publicado el 10 de noviembre: variables de clientes descifradas en como máximo el 1,85% de los workspaces, unos 100.000. Tokens de cuentas vinculadas reseteaddos para 1.852 usuarios. Gasto no autorizado con las claves robadas estimado en unos 740.000 dólares, que Railway está devolviendo o cubriendo con su propio balance.
Y la parte que conviene rumiar: nadie pescó a un director financiero. Nadie lanzó ransomware. El atacante fue a por claves de API de proveedores de IA, y el mercado que hizo que eso valiera un fin de semana de trabajo lo construimos entre todos.
La intrusión, en el orden en que ocurrió
La cronología completa está en el informe de Railway y se lee como una historia de terror contada en marcas UTC.
- 18 de octubre, antes de todo: el atacante empieza a crear cuentas falsas en la plataforma. Las defensas automáticas matan cada intento en esta fase.
- 07:28 UTC, 20 de octubre: explota un fallo desconocido en la infraestructura de build multi-inquilino para escapar parcialmente del aislamiento del sistema de archivos y leer ficheros de la VM anfitriona. De ahí obtiene una credencial que los servidores de build usan para publicar imágenes en un registro.
- 13:58 UTC: llamadas anómalas a la API del registro despiertan al ingeniero de guardia. La causa raíz se encuentra en menos de una hora. Parche fusionado, builds detenidos, atacante aislado.
- El pivote: esa credencial solo debía autorizar subidas al registro. Pero el clúster interno de Temporal que orquesta los builds la aceptaba como cliente de confianza, así que el atacante pudo llamar a sus APIs y leer historiales de build, incluidas las variables que entran en los builds de otros. Uno de esos snapshots era el monorepo interno. La propia plataforma de soporte de Railway se despliega desde ahí, sobre Railway.
- 03:26 UTC, 21 de octubre: escaneando ese código, el atacante encuentra un binding OIDC mal configurado en un entorno cloud y roba credenciales de producción de corta vida.
- 04:07 a 05:21 UTC: con una credencial de más larga vida en una máquina de orquestación, se conectan a la base de datos de producción que guarda las variables cifradas y extraen los sobres. Los logs muestran que seleccionaban filas cuyos nombres de variable coincidían con expresiones regulares de claves de proveedores de IA, priorizando clientes con muchas variables.
- 04:42 a 07:15 UTC: usan la credencial de descifrado de esa misma máquina para abrir los sobres a través del servicio de gestión de claves.
- 07:14 UTC: Railway desactiva todas las credenciales cloud activas, revoca las estáticas, apaga el servicio de descifrado y baja partes de la plataforma. Los builds vuelven a oscuras.
- 09:24 UTC: el atacante queda totalmente expulsado.
Tres decisiones de diseño que convirtieron un bug en un atraco
Quita el drama y el patrón de fallo es conocido, que es justo por lo que importa.
1. Una credencial estrecha en la que confiaban demasiados. Nada en el diseño de esa credencial decía "lee las variables de build de otros inquilinos". La arquitectura simplemente la aceptaba como cliente en otro sitio. El radio de daño no lo define lo que pretendes que haga una clave, sino cada servicio que la acepta.
2. Snapshots en caché que nadie contaba como secretos. La caché de build guardaba copias del estado del repositorio. Eso le dio al atacante un mapa privilegiado de la empresa y, peor, un catálogo de cada ruta que podía probar después.
3. Secretos de larga vida junto a los datos que descifran. El envelope encryption es buen diseño. El envelope encryption donde la máquina que lee el cifrado guarda también la clave que lo abre es una puerta cerrada con la llave puesta. Suma un binding OIDC mal configurado y toda la cadena se cae.
El atacante nunca necesitó un zero-day después de los primeros diez minutos. Todo lo demás era configuración.
Por qué querían tus claves de IA, en concreto
El análisis forense de Railway concluyó que las claves de proveedores de IA eran el objetivo principal. Las claves robadas pasaron a lo que el informe llama estaciones de transferencia distribuidas, el término educado para operaciones de reventa que monetizan los créditos de inferencia de otros. El uso más probable, según el informe, es la destilación: generar datos de entrenamiento y puntuaciones de un modelo frontera a costa de otro.
El informe también corrige la idea de que fue algo aislado. OpenCode, Warp, Fireworks AI y varios más revelaron robos parecidos entre el 6 y el 23 de octubre. Wiz documentó el patrón como "Black October for AI developer platforms". Los propios clientes de Railway vieron las claves robadas usadas para peticiones de agentes de código, revisiones de comportamiento de agentes para crear datos de entrenamiento y comprobaciones de pipelines de entrenamiento y de sus sistemas de puntuación.
En otras palabras: ya existe toda una cadena de suministro ilegal para la inferencia. Las claves son la moneda, el gasto es la pérdida, y las víctimas suelen ser los clientes cuyas variables vivían en la base de datos de otro.
El atacante era un enjambre de agentes, y la defensa también
Dos detalles del informe deberían cambiar cómo piensas los tiempos de respuesta a incidentes.
Primero, el pulso de aquel primer día se describió como una carrera de velocidad entre agentes, con Wiz señalando que la intrusión usó modelos abliterados y un harness de agentes parecido a ARTEX. Treinta y seis horas, docenas de rutas de sondeo en paralelo, cientos de cuentas de prueba.
Segundo, la contramedida de Railway fue igual de mecánica: observación 24/7 del atacante con logs de auditoría y trazas, endurecimiento en paralelo de las rutas sondeadas y análisis forense interno distribuido de forma continua.
Tu runbook de respuesta probablemente asume humanos en una llamada leyendo Slack. Ese ya no es el ritmo del otro lado.
Qué haríamos esta semana
Para cualquiera en el Golfo que corra funciones de IA, agentes o pipelines fintech sobre la plataforma de otro, cinco movimientos:
- Inventaría cada clave de IA y ponle un dueño. OpenAI, Anthropic, OpenRouter, Gemini, Fireworks, las claves BYOK que usan tus agentes. Si una clave no tiene dueño ni fecha de rotación, trátala como expuesta.
- Pon topes y alertas de gasto, no solo de fallos. 740.000 dólares de inferencia no autorizada son una oportunidad de detección. Presupuestos por clave, alertas de picos y una revisión semanal de las claves que solo gastan y nunca despliegan.
- Mata las credenciales de larga vida. Intercambios OIDC de corta vida, una audiencia por servicio y una auditoría permanente de cada binding que hayas configurado alguna vez. La cadena de Railway empezó con un binding simplemente incorrecto.
- Asume que la base de datos de la plataforma es legible por alguien. ¿Qué variables tuyas contienen algo que merezca ser robado? Rota las claves de IA, los tokens de pago y los accesos OAuth de GitHub que guardaste en cualquier plataforma, y prefiere claves que puedas revocar con un clic en el proveedor.
- Mete divulgación y revocación en el contrato. Railway pidió a los proveedores revocar claves por hash antes de saber qué se había filtrado. Pregunta hoy a tus proveedores: ¿pueden producir una lista de hashes y una vía de revocación en cuatro horas tras un incidente?
La frase para recordar
Hay que reconocer a Railway un informe incómodo y inusualmente detallado. Publicó una nota preliminar mientras la recuperación seguía en marcha y el relato forense completo tres semanas después, incluido el hecho de que las claves de sus propios clientes costaron más que la factura anual de una empresa pequeña.
Pero la lección no es que una plataforma fue derrotada. Es que lo más valioso de tu cuenta cloud dejó de ser los datos y pasó a ser el cómputo. Tus claves de IA ya son dinero, y están repartidas en una docena de paneles de variables de entorno en una docena de dashboards, cada una cifrada con una clave que el servidor de build de otro puede leer.
Trátalas como las cuentas bancarias en las que se han convertido en silencio. Rota, limita, pon topes y vigila. Este trimestre, no el siguiente.