Si usas Claude Code o cualquier otro agente de programación con IA, dedica diez minutos a tus repositorios antes que nada. Busca archivos de configuración del agente que se hayan subido con un commit, rota todas las credenciales que contengan y activa el secret scanning de GitHub. Las claves robadas se revenden muy rápido (Unit 42 describe un caso que tardó minutos), así que las comprobaciones van antes que la historia.
Haz estas comprobaciones en tus repos primero
Empieza por el archivo que está en el centro de la historia de Claude Code: .claude/settings.local.json. La firma de seguridad Apiiro encontró 104.185 copias en 103.617 repositorios públicos, y 1.122 de esas copias contenían al menos un secreto (The Hacker News). Así puedes buscar las tuyas.
- Busca el archivo por nombre en toda tu organización de GitHub (cambia el nombre de la organización por el tuyo; requiere la CLI de GitHub).
- Comprueba si el archivo llegó a subirse alguna vez en cada repo en el que trabajas, incluidas las ramas antiguas. El historial conserva lo que el último commit borró.
- Lee las aprobaciones guardadas y busca cualquier cosa que parezca una contraseña, un token o una cadena de conexión.
- Escanea el historial completo y añade una regla para las contraseñas escritas dentro de comandos, que los conjuntos de reglas por defecto suelen pasar por alto.
# 1. Find the files across an organization
gh search code --owner YOUR-ORG --filename settings.local.json
# The same search in the GitHub web search box
# org:YOUR-ORG path:.claude/settings.local.json
# 2. Was it ever committed, on any branch?
git log --all --oneline -- .claude/settings.local.json .claude/settings.json
# 3. List what you have approved with "don't ask again"
jq -r '.permissions.allow[]' .claude/settings.local.json
# 4. Grep the folder and its history for the usual suspects
grep -rEn 'PGPASSWORD=|sshpass -p|mysql -p|AKIA[0-9A-Z]{16}|ghp_[A-Za-z0-9]{20,}' .claude/
git log --all -p -- .claude | grep -E 'PGPASSWORD=|sshpass -p|mysql -p|AKIA[0-9A-Z]{16}'Son llamadas estándar de git, jq y grep, pero trata su salida como una pista, no como un veredicto. La búsqueda de código de GitHub solo ve lo que hay hoy en una rama, y por eso existe el paso 2.
Para el escaneo, Gitleaks y TruffleHog son las dos herramientas que usó Apiiro. Pásalas sobre el historial y luego añade una regla personalizada, porque las reglas por defecto detectan una clave, pero no una contraseña que va después de un flag.
gitleaks git --redact -v .
trufflehog git file://.# .gitleaks.toml
[extend]
useDefault = true
[[rules]]
id = "password-inside-command"
description = "Password passed on a command line"
regex = '''(PGPASSWORD=|sshpass -p |mysql -p)\S+'''Esa regla personalizada se justifica sola. Apiiro pasó ambas herramientas por todos los archivos que encontró: gitleaks marcó 564 de los 1.122 archivos con secretos, TruffleHog marcó 643, y ninguna detectó 215, sobre todo contraseñas escritas después de PGPASSWORD=, sshpass -p o mysql -p (The Hacker News).
Apiiro también recomienda a los equipos de seguridad tratar .claude/, .cursor/, .gemini/, .specstory/ y los archivos de memoria de los agentes como portadores de secretos, igual que .env. Nosotros haríamos la misma búsqueda para cada agente que tenga instalado tu equipo: una transcripción guardada por Cursor, GitHub Copilot o Codex también puede contener una clave pegada.
Cómo un clic de aprobación mete una contraseña en tu repo
Claude Code pregunta antes de ejecutar la mayoría de los comandos de shell. Si eliges "Yes, and don't ask again", escribe una regla de permiso en .claude/settings.local.json. Según la documentación de Anthropic, una aprobación de Bash hecha así dura "permanently per repository and command" (Claude Code docs). El problema está en la forma de la regla. Puede ser un patrón como npm test *, o puede ser el comando exacto, y cuando el comando exacto contiene una contraseña, esa contraseña queda guardada en texto plano.

El archivo debería quedarse en local. Según la documentación de configuración de Anthropic, la primera vez que Claude Code lo escribe en un repo que aún no lo ignora, añade **/.claude/settings.local.json a tus git excludes globales, y un archivo que creas a mano necesita tu propia línea en .gitignore (Claude Code docs). Eso protege un ordenador, no un clon nuevo, un archivo hecho a mano ni uno subido antes de que existiera la regla de ignorado.
Más de un tercio de los secretos que encontró Apiiro abren directamente una base de datos, incluidas 379 contraseñas de bases de datos. El resto incluye 43 accesos SSH a servidores públicos, 42 tokens de GitHub, GitLab y npm, y 23 claves de AWS. Sesenta y tres organizaciones eran dueñas de archivos afectados, y en la mitad de los repos con un secreto el archivo llevaba allí al menos 217 días. Apiiro no probó si alguno sigue funcionando, aunque una empresa a la que avisó confirmó que su clave estaba activa.
La respuesta de Anthropic hasta ahora es un comentario en Hacker News
Un reporte de bug presentado en 2025 fue cerrado por un bot automático como "not planned" tras 60 días sin actividad, y los investigadores de Apiiro dicen que ninguno de los reportes relacionados que citan recibió respuesta de Anthropic (The Hacker News). La respuesta pública llegó en Hacker News, de un comentarista que se presentó como "Boris from the Claude Code team". Escribió que "Historically Claude Code has not done secret scrubbing", que el equipo está "looking into what we can do to prevent this" y que en este caso "the files were manually created and checked in". Añadió que "Permission rules are old hat. Everyone should be using auto mode instead".
Los datos de Apiiro encajan mal con la explicación de los archivos hechos a mano. En 539 de los 1.105 repositorios que rastreó, un commit que citaba a Claude como coautor modificó el archivo. Una línea de coautor no prueba quién ejecutó git, pero cuesta compaginarla con archivos creados a mano. Para nosotros, los datos de los commits son más difíciles de descartar que el comentario, y mientras Anthropic no diga otra cosa, trataríamos el archivo como algo que Claude Code puede subir con un commit.
Grok Build filtró datos dos veces, de maneras distintas
Se están mezclando dos historias de Grok Build, y cada una necesita una solución distinta. (La prensa llama a la empresa SpaceXSI o SpaceXAI.)
La primera llegó a principios de 2026. Un investigador que publica como cereblab analizó Grok Build 0.2.93 y reportó que subía repositorios Git enteros bajo seguimiento, con su historial de commits, secretos subidos y claves de API, a almacenamiento en la nube (The Next Web). Según ese análisis, la subida era unas 27.800 veces mayor de lo que necesitaba la tarea, y el interruptor de privacidad, según se informa, no hacía nada. xAI había promocionado la herramienta con la frase "nothing from your codebase transmitted to xAI servers during a session". Elon Musk reconoció las transferencias y dijo que se borrarían los datos previos de los usuarios. TNW añade que ninguna auditoría independiente ha confirmado el borrado.
La segunda es la que ahora es noticia, y no tiene nada que ver con repositorios. La firma de seguridad Claroc descubrió que los enlaces para compartir de Grok Build pueden ser encontrados por personas a las que nunca se los enviaron (Claroc). Engadget cuenta que cada enlace usaba una frase aleatoria de cuatro palabras con hasta 38 bits de entropía, colocada "to the left of the domain" (Engadget). Eso la deja en el hostname, y Claroc explica que los servicios de DNS pasivo recogen esas consultas. Los chats compartidos de ChatGPT y Gemini guardan su secreto en la ruta de la URL, que el DNS nunca ve. "Nobody would guess one", escribe Claroc, "and nobody needs to, because the dataset lists them".
Las apps expuestas contenían material real. Claroc enumera un mapa de territorios de ventas con 594 cuentas estratégicas, ocho propuestas publicitarias de X, cuatro paneles de cuentas de anunciantes en vivo, la app del personal de un grupo hospitalario con una lista de más de 3.500 empleados y el panel de turnos en vivo de un cuerpo de bomberos con el nombre y el número de placa de cada bombero. De las direcciones que probó, el 94,7 % se abría sin iniciar sesión. Claroc estima que alrededor del 2 % de las apps contenía material lo bastante grave como para calificarse de alto o crítico.
Claroc dice que SpaceXSI retiró las 24 apps que había creado su personal, "but not the apps of other Grok users and organizations". Engadget añade que la empresa, según se informa, no respondió hasta que Claroc etiquetó a Musk y a otro directivo de la empresa en X. La publicación de Claroc dice que SpaceXSI respondió a las preguntas de un periodista, diciendo que las apps de Grok son privadas hasta que su creador decide compartirlas, pero no había respondido al reporte en sí. No hemos encontrado ninguna declaración que diga que las demás apps se retirarán.
La solución para los usuarios es tajante. Trata como público todo lo que construyas o compartas con Grok Build, elimina los enlaces que no necesites y rota cualquier credencial que haya tocado una app que compartiste. Aquí no sirve de nada una línea en .gitignore.
Las claves robadas se revenden en minutos
Unit 42, de Palo Alto Networks, describe el "token jacking": claves de API de IA robadas que se revenden a través de "transfer stations" del mercado gris, que venden acceso con descuento a modelos de frontera (Unit 42). Entre las fuentes de claves que enumera están los repositorios de código expuestos, los infostealers y los paquetes npm envenenados. En un caso, los atacantes integraron credenciales expuestas en una transfer station en cuestión de minutos, y siguieron "nearly a million dollars in charges" antes de que se descubriera. Unit 42 dice que las víctimas tienen "very little recourse to recover funds". Sus defensas son las aburridas de siempre: límites de gasto con alertas, tokens de corta duración en lugar de claves de larga duración y una revisión de todas las cuentas con privilegios que pueden ajustar los límites.
Arregla la fuga: ignora, deja de rastrear y rota
Primero rota, después limpia. Una clave revocada no sirve de nada en ningún fork ni copia en caché, mientras que una clave que solo borraste del último commit sigue activa en el historial. GitHub dice que hay que rotar de inmediato una credencial expuesta, y califica la limpieza del historial de "time-intensive and often unnecessary if you've already revoked the credential" (GitHub docs).
# Rotate the exposed credentials first (table below), then:
# Stop tracking the local file (keeps your copy on disk)
git rm --cached .claude/settings.local.json
# Add to the repo's OWN .gitignore, not just your global excludes
printf '%s\n' '.claude/settings.local.json' '.specstory/' >> .gitignore
git add .gitignore
git commit -m "Stop tracking agent local settings"
# Drop any allow rule that looks like it holds a secret, even if never committed
jq '.permissions.allow |= map(select(test("PGPASSWORD|password|token|secret|key"; "i") | not))' \
.claude/settings.local.json > .claude/settings.local.json.new \
&& mv .claude/settings.local.json.new .claude/settings.local.jsonPiénsalo antes de ignorar .cursor/ o .gemini/ por completo, porque algunos equipos suben ahí reglas compartidas a propósito.
Cómo rotar claves en los principales proveedores
Todos los proveedores tienen un botón en su consola para esto, y el orden seguro es crear el reemplazo, desplegarlo y después eliminar la clave antigua. Si borras primero, puedes tumbar producción.
| Proveedor | Cómo rotar | Notas |
|---|---|---|
| AWS | Crea una segunda clave de acceso de IAM, actualiza tus apps, comprueba el último uso, desactiva la clave antigua y luego bórrala | aws iam create-access-key, get-access-key-last-used, update-access-key --status Inactive, delete-access-key (AWS docs) |
| GitHub | Borra el token y crea uno nuevo con fecha de caducidad | GitHub revoca automáticamente los tokens subidos a un repositorio o gist público; para una fuga en cualquier otro sitio puedes enviar una solicitud de revocación a través de la API REST (GitHub docs) |
| Stripe | Haz un roll de la clave en el Dashboard y usa claves restringidas a partir de ahora | Rota aunque no estés seguro de que alguien la viera; Stripe puede desactivar una clave que detecte (Stripe docs) |
| OpenAI | Crea un reemplazo, actualiza tus apps y revoca la clave antigua cuando el nuevo funcione | Define una caducidad para las claves de proyecto y usa una cuenta de servicio de proyecto para las apps (OpenAI docs) |
Para cualquier proveedor que no esté en la tabla, incluidos Anthropic y xAI, no hemos verificado los pasos de rotación, así que sigue su propia documentación. Para contraseñas de bases de datos y accesos SSH, el grueso de lo que encontró Apiiro, cambia la contraseña, cierra las sesiones abiertas y revisa los logs de acceso desde el día en que el archivo se subió por primera vez.
Activa los escáneres de GitHub y conoce sus límites
El secret scanning revisa el historial completo de todas las ramas, además de issues, pull requests, discussions y wikis. Es gratuito y automático en los repositorios públicos; para los repos privados e internos de una organización requiere GitHub Secret Protection (GitHub docs). Cuando se detecta el formato de clave de un partner, GitHub avisa a ese proveedor, que puede revocar la clave sin que aparezca ninguna alerta en tu repositorio.
Push protection es la capa que habría frenado muchos de estos archivos antes de hacerse públicos. Bloquea un push que contiene un secreto detectado. Según la documentación de GitHub, el ajuste a nivel de usuario viene activado por defecto para los pushes a repositorios públicos en GitHub.com, mientras que el ajuste a nivel de repositorio viene desactivado por defecto y lo tiene que activar un admin del repo, un propietario de la organización o un security manager (GitHub docs). Analiza patrones de proveedores, patrones genéricos como claves privadas y cadenas de conexión, tus patrones personalizados y una categoría detectada por IA para secretos no estructurados, como las contraseñas, en vista previa pública. Esa última categoría parece pensada para el hueco que encontró Apiiro. Los pushes por la API REST no la tienen; los pushes desde la línea de comandos, los commits desde la interfaz web y las subidas de archivos sí.
Conoce también la vía de escape. Por defecto, cualquiera con acceso de escritura puede saltarse un bloqueo eligiendo un motivo, como "I'll fix it later", lo que abre una alerta y envía un correo a los propietarios. Si tus agentes hacen commits en tu nombre, configura el bypass delegado para que solo personas concretas puedan dejar pasar un secreto.
Ajustes de permisos del agente que debes cambiar hoy
Tres hábitos habrían mantenido la contraseña fuera del archivo. Aprueba patrones, nunca comandos literales con credenciales. Pon los secretos en variables de entorno para que el comando lleve un nombre y no un valor. Y niega al agente el acceso a los archivos que guardan secretos desde el principio. La documentación de configuración de Anthropic muestra cómo:
{
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)"
]
}
}El comando que debería ejecutar tu agente es algo como psql "$DATABASE_URL", de modo que la regla de aprobación guarda un nombre de variable y nada más. Carga la variable desde un gestor de secretos o desde el perfil de tu shell, no desde un archivo que el agente pueda leer.
Dos detalles de la documentación importan para los equipos: las reglas allow del .claude/settings.json que se sube al repo esperan a que cada compañero confíe en la carpeta, mientras que las reglas deny y ask se aplican de inmediato, y los modos auto y bypassPermissions no surten efecto desde la configuración del proyecto ni la local. Las organizaciones pueden bloquear las reglas allow con allowManagedPermissionRulesOnly. El miembro del equipo de Claude Code citado antes dice que el modo auto hace innecesarias las reglas de permisos. Nosotros mantendríamos igualmente las reglas deny para .env: dos líneas, aplicadas en el momento en que se sube el archivo.
En otras herramientas los nombres de los ajustes cambian, pero la pregunta es la misma: ¿dónde guarda la herramienta las aprobaciones, el historial o las transcripciones, y ese lugar está dentro de un repo? Según la documentación, Apiiro encontró que Claude Code es el único de los 16 agentes de programación que comparó cuyo guardado del comando aprobado completo en un archivo del proyecto, por defecto, está confirmado. Los otros quince pueden filtrar igualmente a través de transcripciones, claves pegadas y archivos de memoria. Nuestra comparativa de agentes de programación para terminal y el artículo Cursor vs Copilot vs Windsurf cubren lo que guarda cada uno.
El control más fuerte no depende de un prompt. Ejecuta los agentes en un contenedor o sandbox con solo las credenciales que necesita esa tarea, con alcances limitados y vida corta. Explicamos el funcionamiento en Cómo contener a un agente de IA.
Los usuarios son responsables de la rotación; los proveedores, del valor por defecto
Escribir una contraseña en un comando es un error del usuario, y el usuario es responsable de la rotación. Pero una herramienta que guarda el comando completo en un archivo del proyecto y luego confía en un exclude en tu directorio personal para mantenerlo privado tiene una protección que solo funciona en un portátil.

Los valores por defecto son política, y aquí el valor por defecto decidió el resultado. Un Claude Code que limpiara los secretos antes de guardar una regla, o que escribiera la línea de ignorado en el .gitignore del propio repo, habría cerrado el agujero en origen. Anthropic dice que lo está estudiando (nos gustaría una fecha). Un reporte de bug cerrado por un bot de inactividad no tranquiliza, y los datos de los commits no encajan con "manually created".
Grok Build es el peor caso en la historia de los enlaces compartidos, porque el usuario no hizo nada mal. Un enlace que cualquiera puede encontrar mediante DNS pasivo no es privado, diga lo que diga el menú de compartir. Y la subida anterior contradecía una frase de marketing que decía justo lo contrario. No meteríamos una lista de clientes, un mapa de territorios de ventas ni una credencial de producción en Grok Build hasta que se arregle el problema de los enlaces compartidos y una auditoría externa confirme el borrado. Si eso cambia, nuestra opinión también.
Trata las carpetas de los agentes como archivos .env y reserva una tarde para la configuración de arriba. Puedes comparar las propias herramientas en nuestro ranking de asistentes de programación con IA, y el lado de seguridad del ecosistema en el ranking de herramientas de ciberseguridad con IA.
Una checklist para todo el equipo
Marca lo que se cumple hoy y la puntuación te dirá por dónde empezar. Los elementos de dos puntos son los que haríamos antes de comer.
Preguntas frecuentes
¿Es seguro subir .claude/settings.local.json al repo?
No. Contiene tus aprobaciones personales y puede contener credenciales. La documentación de Anthropic dice que Claude Code lo mantiene fuera de git cuando crea el archivo, mediante un exclude global, y que una copia hecha a mano necesita tu propia línea de ignorado. Añádelo al .gitignore de cada repo y deja de rastrearlo con git rm --cached si alguna vez se subió.
¿Tengo que rotar las claves si mi repo es privado?
Sí, si el archivo llegó a contener alguna credencial. Los repos privados se clonan en portátiles y runners de CI, se hacen fork a otras cuentas y a veces se pasan a públicos. El secret scanning de GitHub para repos privados de organizaciones requiere un plan de pago, así que puede que el tuyo no tuviera ninguna comprobación automática.
¿Borrar el archivo de mi repo elimina el secreto?
Lo elimina del último commit y nada más. El historial, los forks y las cachés conservan la versión antigua, y Apiiro encontró 734 secretos que solo aparecen en versiones anteriores del archivo. Rota primero la credencial y reescribe el historial solo si quieres un repo ordenado.
¿GitHub Copilot, Cursor y Codex tienen el mismo problema?
Apiiro confirmó este comportamiento, guardar por defecto el comando aprobado completo en un archivo del proyecto, solo en Claude Code de entre los 16 agentes que comparó. Eso no exculpa a los demás. Cualquier agente que escriba transcripciones o memoria en tu directorio de trabajo necesita las mismas reglas de ignorado.