Volver al blog

Filtración en OpenCode Console en 2026: Cómo Proteger Tus Claves de API de IA

Hola HaWkers, el sábado 17 de octubre de 2026, OpenCode, uno de los agentes de código open source más usados en la terminal, confirmó que sufrió una intrusión. Claves de API de OpenAI, Anthropic y Google que algunos usuarios habían guardado en OpenCode Console pueden haber quedado expuestas. En pocas horas aparecieron reportes de cobros que nadie autorizó: desde unos cientos de dólares hasta US$ 1.700 en una sola noche. La discusión en Hacker News superó los 970 puntos.

El caso es pequeño en número de personas afectadas, pero grande en lo que enseña. La pregunta que todo dev que usa IA en el día a día debería hacerse ahora es simple: si la herramienta donde guardé mi clave fuera invadida hoy, ¿cuánto perdería hasta darme cuenta? En este artículo vas a entender qué pasó realmente, qué todavía no se sabe, y vas a salir con una guía práctica, con código, para revocar, probar y limitar tus claves de API de IA.

Qué Pasó en OpenCode Console

Primero, una distinción importante. OpenCode tiene dos partes:

  • La app y la CLI open source, que corren en tu máquina. Cuando conectas un proveedor con el comando /connect, la clave queda guardada localmente, en ~/.local/share/opencode/auth.json.
  • OpenCode Console, la plataforma online de la empresa. Ahí, un workspace puede conectar cuentas de proveedores para que los miembros del equipo usen los modelos sin ver nunca la clave del proveedor. Por lo tanto, la clave queda guardada en los servidores de OpenCode.

El incidente afectó solo a Console. Según el cofundador Dax Raad, la app y la CLI open source no fueron afectadas, y las claves usadas en OpenCode local nunca llegan a la empresa.

La línea de tiempo divulgada hasta ahora:

  • 17/10, 00:30 UTC: hora más temprana de posible exposición de las claves, según el correo enviado a los afectados.
  • 17/10: el investigador de seguridad Matt Johansen publica en X la captura del correo con el asunto "Action Required: Potential provider key breach".
  • 17/10: OpenCode confirma públicamente una violación de seguridad "relacionada con un ataque de destilación a gran escala".
  • 19/10: TechCrunch y BleepingComputer publican los primeros reportajes completos.

La empresa dijo que la intrusión ocurrió en un sistema legado que ya estaba siendo desactivado y que el 1,4% de los usuarios de Console fueron afectados. Quien no recibió el correo no fue impactado.

Qué Se Expuso y Cuánto Costó

Lo que se filtró fueron las claves de proveedores externos guardadas en los workspaces de Console. El correo menciona OpenAI y Anthropic como ejemplos, y los reportajes incluyen también claves de Google. La empresa afirmó que ningún otro dato parece haber sido expuesto.

El impacto apareció primero en la factura. Desarrolladores reportaron alertas de gasto de OpenAI, Anthropic y Google, con cobros de cientos de dólares y algunos totales por encima de US$ 1.000. El mayor valor reportado fue de US$ 1.700 de un día para otro. Algunos usuarios también tuvieron proyectos suspendidos por Google, con la justificación de "actividad abusiva consistente con recursos secuestrados".

La respuesta de los proveedores fue rápida:

  • Anthropic y Google bloquearon las claves que creían expuestas.
  • OpenAI trabajó con OpenCode para restaurar el acceso y reembolsó los créditos usados en el ataque.
  • OpenCode dijo que los reembolsos de cobros no autorizados están en curso.

Qué Es un "Ataque de Destilación"

OpenCode eligió el término distillation attack para describir el incidente, y eso generó debate. La destilación, por sí sola, es una técnica legítima: entrenas un modelo más pequeño usando las respuestas de un modelo más grande y capaz. Se convierte en ataque cuando las respuestas se obtienen a gran escala, sin autorización y, muchas veces, pagadas por otra persona.

La lógica económica es cruel. Una clave robada es salida de un modelo de punta gratis para el atacante, cobrada en la tarjeta del dueño de la clave. Cuanto más caro es el modelo, más valiosa es la clave.

Vale la pena aclarar que no todo el mundo se creyó esa explicación. Parte de la comunidad argumentó que el caso es simplemente una filtración, y que la relación con la destilación todavía no se ha probado. OpenCode tampoco explicó cómo entraron los atacantes, cómo se almacenaban las claves ni el alcance total del uso indebido. La empresa dice que el incidente sigue en curso.

La Parte Más Extraña: IA Negándose a Defender

Un detalle del relato de Dax Raad llamó la atención. Contó que los atacantes intentaron invadir los sistemas sin parar durante al menos 48 horas, usando agentes de IA, y que el equipo puso agentes defensivos de IA a trabajar todo el tiempo.

El problema: los modelos usados en la investigación ayudaron al principio, pero se negaron a continuar cuando el código malicioso activó los filtros de seguridad. Raad lo calificó como "un poco frustrante". La situación solo se estabilizó cuando OpenCode obtuvo acceso al programa Daybreak de OpenAI, que ofrece a usuarios verificados modelos menos propensos a rechazar trabajo de seguridad defensiva.

No es la primera vez que pasa en 2026. En julio, Hugging Face reportó que modelos comerciales se negaron a analizar logs de una intrusión hecha por agentes autónomos y resumió el dilema: los guardrails "no logran distinguir a quien responde a un incidente de quien ataca". Si tu plan de respuesta a incidentes depende de un asistente de IA, ten un plan B.

Por Qué los Agentes de Código Se Volvieron un Imán de Credenciales

El caso de OpenCode es síntoma de algo más grande. Las herramientas de IA para código concentran exactamente lo que un atacante quiere:

  • Claves de varios proveedores en el mismo lugar, muchas veces sin límite de gasto.
  • Claves de alto valor, porque dan acceso a los modelos más caros.
  • Un uso que ya es intenso por naturaleza, así que un pico de consumo tarda en parecer anormal.

Y la filtración no necesita venir de una intrusión sofisticada. Las claves de IA expuestas en repositorios públicos ya son un problema antiguo, como mostré en el artículo sobre empresas de IA que expusieron API keys en GitHub. Y los agentes atacando la cadena de suministro ya son una realidad, como en el ataque a RubyGems hecho con agentes de OpenAI.

La conclusión práctica: trata cada clave de IA como una tarjeta de crédito sin límite, porque, sin configuración, eso es lo que es.

Guía Práctica: Cómo Proteger Tus Claves de IA

Ahora la parte que interesa a quien fue afectado y, sobre todo, a quien no lo fue. Son cuatro pasos, del más urgente al más estructural.

Paso 1: Revoca y Confirma Que la Clave Murió

Si recibiste el correo de OpenCode, o si tenías cualquier clave en Console, la recomendación oficial es revocar y reemplazar la clave directamente en el panel de cada proveedor. Cambiar la contraseña de OpenCode o borrar la configuración local no invalida una clave que ya se filtró.

Después de revocar, confirma. Una clave revocada debe responder HTTP 401 en una llamada de prueba. El script de abajo prueba las tres a la vez, sin gastar tokens, porque solo lista los modelos disponibles:

#!/usr/bin/env bash
# check-keys.sh - confirma si las claves antiguas fueron realmente revocadas
# Uso: OLD_OPENAI_KEY=... OLD_ANTHROPIC_KEY=... OLD_GEMINI_KEY=... ./check-keys.sh

check() {
  local name="$1" status="$2"
  if [ "$status" = "401" ] || [ "$status" = "403" ] || [ "$status" = "400" ]; then
    echo "OK    $name revocada (HTTP $status)"
  else
    echo "ALERTA $name todavía responde (HTTP $status) - revócala ahora"
  fi
}

# OpenAI: endpoint de listado de modelos, no consume tokens
if [ -n "$OLD_OPENAI_KEY" ]; then
  s=$(curl -s -o /dev/null -w "%{http_code}" https://api.openai.com/v1/models \
    -H "Authorization: Bearer $OLD_OPENAI_KEY")
  check "OpenAI" "$s"
fi

# Anthropic: misma idea, con los headers obligatorios
if [ -n "$OLD_ANTHROPIC_KEY" ]; then
  s=$(curl -s -o /dev/null -w "%{http_code}" https://api.anthropic.com/v1/models \
    -H "x-api-key: $OLD_ANTHROPIC_KEY" -H "anthropic-version: 2023-06-01")
  check "Anthropic" "$s"
fi

# Gemini: la clave va como query string
if [ -n "$OLD_GEMINI_KEY" ]; then
  s=$(curl -s -o /dev/null -w "%{http_code}" \
    "https://generativelanguage.googleapis.com/v1beta/models?key=$OLD_GEMINI_KEY")
  check "Gemini" "$s"
fi

Un consejo para Gemini: crea la clave nueva en AI Studio antes de desactivar la antigua, para no tumbar lo que está en producción en medio del cambio.

Paso 2: Encuentra Todos los Lugares Donde Vive la Clave Antigua

Revocar sin actualizar rompe tus aplicaciones; actualizar sin buscar deja la clave antigua escondida en algún .env olvidado. Antes de cerrar el incidente, revisa el proyecto y tu home buscando los formatos conocidos de clave:

# find-ai-keys.sh - busca claves de IA en texto plano
# Prefijos comunes: sk-ant- (Anthropic), sk-proj- / sk- (OpenAI), AIza (Google)
PATTERN='(sk-ant-[A-Za-z0-9_-]{20,}|sk-proj-[A-Za-z0-9_-]{20,}|sk-[A-Za-z0-9]{32,}|AIza[0-9A-Za-z_-]{35})'

# Archivos del proyecto actual, ignorando node_modules y .git
grep -rEn --exclude-dir={node_modules,.git,dist} "$PATTERN" . 2>/dev/null \
  | sed -E 's/(sk-ant-|sk-proj-|sk-|AIza)[A-Za-z0-9_-]{6}[A-Za-z0-9_-]*/\1******/g'

# Historial de git: la clave puede haber sido eliminada del archivo, pero no del commit
git log -p --all 2>/dev/null | grep -Eo "$PATTERN" | cut -c1-12 | sort -u

El sed enmascara la clave en la salida, para que no pegues un secreto en una terminal compartida o en una captura. Si algo aparece en el historial de git, revocar es obligatorio: reescribir el historial no deshace el hecho de que la clave fue publicada.

No olvides los lugares fuera del código: secrets de CI (GitHub Actions, Vercel, Railway), variables en el servidor, el propio workspace de OpenCode Console y cualquier otra herramienta de IA donde hayas pegado la misma clave.

Paso 3: Limita el Daño Antes del Próximo Incidente

La segunda mitad de la lección es reducir el tamaño del perjuicio cuando, y no si, una clave se filtre de nuevo:

  • Una clave por servicio. Si OpenCode, tu backend y tu script de pruebas usan la misma clave, tienes que cambiar todo a la vez y no sabes de dónde vino el gasto.
  • Límite de gasto. En Anthropic, los workspaces permiten definir un límite mensual propio, siempre por debajo del límite de la organización, y las claves quedan atadas al workspace donde fueron creadas. En OpenAI, los límites están a nivel de organización y de proyecto, así que crea un proyecto separado para cada herramienta.
  • Alcance mínimo. Google recomienda restringir las claves de Gemini solo a la API de Gemini.
  • Monitoreo por clave, para que una anomalía aparezca pronto.

Para el último punto, se puede armar una alerta simple. El ejemplo de abajo, en Node.js, compara el gasto de la última hora con el promedio de la semana y dispara un aviso cuando el salto es grande. La función fetchHourlySpend es un punto de integración: conéctala a la API de uso de tu proveedor o a tu propio log de llamadas.

// spend-alert.mjs - alerta de pico de gasto por clave de API
// fetchHourlySpend(keyId) debe devolver un array con el gasto (US$) de las últimas 168 horas
import { fetchHourlySpend } from './usage-source.mjs';

const KEYS = ['opencode-local', 'backend-prod', 'ci-tests'];
const SPIKE_FACTOR = 5; // 5x por encima del promedio ya merece atención
const MIN_ABSOLUTE = 10; // ignora picos por debajo de US$ 10

async function checkKey(keyId) {
  const hours = await fetchHourlySpend(keyId);
  const lastHour = hours.at(-1) ?? 0;
  const history = hours.slice(0, -1);
  const avg = history.reduce((sum, v) => sum + v, 0) / Math.max(history.length, 1);

  // Solo alerta cuando el salto es relativo Y absoluto, para evitar ruido
  if (lastHour > MIN_ABSOLUTE && lastHour > avg * SPIKE_FACTOR) {
    return `Clave ${keyId}: US$ ${lastHour.toFixed(2)} en la última hora (promedio US$ ${avg.toFixed(2)})`;
  }
  return null;
}

const alerts = (await Promise.all(KEYS.map(checkKey))).filter(Boolean);

if (alerts.length > 0) {
  // Cámbialo por Slack, correo o PagerDuty
  console.error('Pico de gasto detectado:\n' + alerts.join('\n'));
  process.exitCode = 1;
}

Ejecutando esto cada 15 minutos en un cron, un ataque como el de OpenCode se detectaría en minutos, no a la mañana siguiente, cuando la factura ya llegó a US$ 1.700.

Paso 4: Cuida También las Claves Locales

El incidente no afectó a la CLI, pero vale la pena revisarla. Las claves guardadas localmente están en texto plano en un archivo de tu home. Cualquier proceso que corra con tu usuario puede leerlo, y eso incluye un paquete npm malicioso o una extensión comprometida. Lo mínimo es garantizar que solo tu usuario tenga acceso:

# Verifica y corrige el permiso del archivo de credenciales de OpenCode
AUTH="$HOME/.local/share/opencode/auth.json"

if [ -f "$AUTH" ]; then
  ls -l "$AUTH"          # debe mostrar -rw------- (600)
  chmod 600 "$AUTH"      # lectura y escritura solo para el dueño
fi

# Extra: nunca dejes que el archivo entre en backups sincronizados o en dotfiles públicos
grep -q "opencode/auth.json" ~/.gitignore_global 2>/dev/null \
  || echo ".local/share/opencode/auth.json" >> ~/.gitignore_global

El permiso de archivo no protege contra todo, pero cierra la puerta a la filtración más tonta: el archivo terminando en un repositorio de dotfiles público.

Lo Que Todavía No Sabemos

Para mantener los pies en la tierra, esto es lo que sigue abierto al momento de publicar este artículo:

  • Cuántas cuentas exactamente corresponden al 1,4% de los usuarios de Console.
  • Cómo entraron los atacantes al sistema legado y durante cuánto tiempo tuvieron acceso.
  • Cómo se almacenaban las claves y si todas fueron realmente copiadas.
  • Si la etiqueta de "ataque de destilación" se confirma o si es solo una filtración con uso indebido de las claves.

Si usas Console, sigue los canales oficiales de OpenCode y revisa el uso de tus claves al menos desde el 16 de octubre.

Perspectivas: La Clave de API Se Volvió un Activo Financiero

El incidente de OpenCode muestra que, en 2026, los atacantes tratan una clave de API de IA como dinero, y con razón. Los modelos más caros cuestan caro por token, y una clave sin límite es crédito ilimitado para quien la encuentre. Al mismo tiempo, las plataformas que guardan claves "para facilitarle la vida al equipo" pasan a ser objetivos tan valiosos como una pasarela de pagos.

La buena noticia es que la defensa no exige nada exótico: una clave por servicio, límite de gasto en todas, monitoreo por clave y el hábito de probar si la clave antigua realmente murió. Quien ya hacía esto vio el incidente como una noticia. Quien no lo hacía, lo vio en la factura.

¡Vamos con todo! 🦅

📚 ¿Quieres Seguir lo Que Viene Por Delante?

Este artículo cubrió la filtración de claves de API en OpenCode Console y cómo proteger tus claves de IA, pero el ecosistema cambia cada semana y no todo se convierte en artículo aquí.

En X comparto lo que estoy probando, los bastidores de los proyectos y las novedades que aparecen antes de convertirse en post.

Sígueme Allá

👉 Seguir a @jeffbruchado en X

💡 Contenido diario sobre desarrollo, carrera y las herramientas que realmente uso

Comentarios (0)

Este artículo aún no tiene comentarios 😢. ¡Sé el primero! 🚀🦅

Añadir comentarios