En vivo 18.11 · Cohorte 318 nov, 19:00 MSK — taller práctico gratuito de agentes IA · Cohorte 3 en vivo inicia 23.11Taller 18 nov →Cohorte 3 (23.11)
LanzamientoCódigo / SDK · Listo para usarGitLab Blog→ original

Claude Code guarda tokens en un archivo y 1 122 repositorios los han expuesto públicamente

Cuando un desarrollador pulsa «Yes, and don't ask again» en Claude Code, el agente guarda el comando completo en .claude/settings.local.json. Si el comando incluía un token o una contraseña, el secreto queda en el archivo. Claude añade la protección frente a git solo en el exclude global del portátil, así que el archivo se puede commitear sin problemas. Según Apiiro, en repositorios públicos se encontraron 104 185 copias, y 1 122 de ellas contenían al menos un secreto.

Procesado por IA desde GitLab Blog; editado por Hamidun News
Claude Code guarda tokens en un archivo y 1 122 repositorios los han expuesto públicamente
Fuente: GitLab Blog. Collage: Hamidun News.
Escuchar artículo
Ficha técnica y cifras clave
ParámetroDatos
Fuente originalGitLab Blog ↗
Editor jefe
Dato clave #1Añada .claude/settings.local.json al .gitignore de cada proyecto
Dato clave #2Prohíba el nombre del archivo con una regla de push a nivel de grupo en GitLab
Revise el historial de commitsun archivo eliminado también es una fuga

Es una situación conocida: el agente pide permiso para ejecutar un comando de shell, usted está cansado de confirmar siempre lo mismo y pulsa «Yes, and don't ask again». Claude Code recuerda la elección y escribe el comando en el archivo .claude/settings.local.json dentro del proyecto. El problema es que el comando se guarda literalmente. Si llamó a una API con curl y la cabecera PRIVATE-TOKEN, el token quedará en ese archivo en texto plano.

Por qué el archivo termina en el repositorio

Para que el archivo no llegue a git, Claude Code lo añade al exclude global personal del desarrollador, no al .gitignore del proyecto. Esa protección vive en un único portátil y no viaja con el repositorio. Un compañero, un entorno de CI o un segundo ordenador no conocen esa exclusión. git add . recoge el archivo y este acaba donde esté alojado el repositorio.

La empresa Apiiro estimó la magnitud del problema a principios de noviembre de 2026. En repositorios públicos encontró 104 185 copias del archivo, y 1 122 de ellas contenían al menos un secreto. Otros cientos de secretos permanecen solo en el historial, en archivos que ya se eliminaron. Borrar el archivo no revierte la fuga: el token sigue en los commits antiguos.

La guía de GitLab está escrita para quienes alojan su código allí, pero su lógica se puede trasladar a cualquier servicio de alojamiento git. GitLab afirma, además, que sus propios secretos de infraestructura están protegidos.

Cómo cerrar la brecha: cuatro capas

El grupo se configura una sola vez y, a partir de ahí, la protección funciona sola. Las capas van de la más sencilla a la más compleja.

1. .gitignore. La opción más barata: la línea .claude/settings.local.json en cada repositorio. En los planes Premium y Ultimate se puede incluir en el .gitignore del proyecto plantilla del grupo, y todos los proyectos nuevos la heredarán automáticamente.

2. Regla de push (Premium y Ultimate). En la configuración del grupo, en la sección de nombres de archivo prohibidos, se indica la expresión regular (^|/)\\.claude/settings\\.local\\.json$. Se rechazará cualquier push que incluya ese archivo, en la raíz o en una subcarpeta y en cualquier rama, y el desarrollador verá un mensaje con el patrón.

3. Secret Push Protection (Ultimate). Esta capa no mira el nombre del archivo, sino el contenido del push. Si encuentra un token con un formato conocido, rechaza el push. Sirve incluso cuando el secreto acabó en un archivo con otro nombre.

4. Política de escaneo (Ultimate). Una política en el nivel superior del grupo ejecuta Secret Detection en cada proyecto, incluso sin .gitlab-ci.yml, y los proyectos individuales no pueden desactivarla. Una regla se activa en cada pipeline y la otra, según una programación semanal. Con la variable SECRET_DETECTION_HISTORIC_SCAN: 'true', la programación revisa todo el historial y no solo los commits nuevos.

Trampas habituales

Las reglas de push tienen dos limitaciones. Primero, solo comprueban la adición de archivos, no los cambios en archivos que ya están bajo seguimiento, así que hay que eliminar antes las copias existentes. Segundo, la regla del grupo se copia únicamente a los proyectos creados después de que exista. En los proyectos antiguos hay que definirla por separado, por ejemplo mediante la API: POST /api/v4/projects/<id>/push_rule con el parámetro file_name_regex. Si el proyecto ya tiene sus propias reglas, use PUT; de lo contrario obtendrá el error 422 Project push rule exists.

Cómo saber si usted tiene el problema

Primero hace falta una lista de los repositorios afectados. Hay tres vías:

  • GitLab Duo Agentic Chat. Se le pide al chat que encuentre todos los proyectos del grupo donde alguna vez existió este archivo, incluidas las copias eliminadas y otras ramas. En un grupo de unos cien proyectos tarda varios minutos. A cambio, encuentra lo que la búsqueda no ve.
  • Búsqueda de código (Premium y Ultimate). Es rápida, pero solo ve la rama por defecto en su estado actual. La sintaxis depende del motor: para exact code search, file:\\.claude/settings\\.local\\.json$ con expresiones regulares; para advanced search, filename:settings.local.json path:.claude. En la API mantenga exclude_forks=false; de lo contrario, los forks desaparecerán de los resultados.
  • Commits API (todos los planes). La consulta repository/commits?path=.claude/settings.local.json&all=true en cada proyecto muestra si el archivo existió en alguna rama. Una respuesta vacía significa que el archivo nunca existió. Los forks se comprueban igual que los proyectos normales.

Qué hacer en la práctica

Empiece buscando en el historial, no en el estado actual: los archivos eliminados son los más peligrosos porque se olvidan. Considere comprometido todo lo que haya aparecido en el archivo y regenere esas credenciales, aunque el repositorio sea privado. Después active la protección: al menos .gitignore y la regla de push y, con Ultimate, también la revisión del contenido.

Una reflexión aparte para los equipos que están incorporando agentes: el botón «no volver a preguntar» convierte un permiso puntual en un registro permanente de comandos, y los secretos de esos comandos terminan allí con ellos. No pase tokens al agente como argumentos de la línea de comandos; use variables de entorno o un gestor de secretos, y así el comando guardado será seguro.

Limitación: en el texto proporcionado, la guía se interrumpe antes de la sección sobre limpieza masiva, por lo que el procedimiento para limpiar el historial debe consultarse en el original.

Historia

Preguntas frecuentes sobre la noticia

¿Qué se sabe sobre Por qué el archivo termina en el repositorio?

Para que el archivo no llegue a git, Claude Code lo añade al exclude global personal del desarrollador, no al .gitignore del proyecto. Esa protección vive en un único portátil y no viaja con el repositorio. Un compañero, un entorno de CI o un segundo ordenador no conocen esa exclusión. git add . recoge el archivo y este acaba donde esté alojado el repositorio. La empresa Apiiro estimó la magnitud del problema a principios de noviembre de 2026.

Cómo cerrar la brecha: cuatro capas?

El grupo se configura una sola vez y, a partir de ahí, la protección funciona sola. Las capas van de la más sencilla a la más compleja. 1. .gitignore. La opción más barata: la línea .claude/settings.local.json en cada repositorio. En los planes Premium y Ultimate se puede incluir en el .gitignore del proyecto plantilla del grupo, y todos los proyectos nuevos la heredarán automáticamente. 2. Regla de push (Premium y Ultimate).

¿Qué se sabe sobre Trampas habituales?

Las reglas de push tienen dos limitaciones. Primero, solo comprueban la adición de archivos, no los cambios en archivos que ya están bajo seguimiento, así que hay que eliminar antes las copias existentes. Segundo, la regla del grupo se copia únicamente a los proyectos creados después de que exista. En los proyectos antiguos hay que definirla por separado, por ejemplo mediante la API: POST /api/v4/projects/<id>/push_rule con el parámetro file_name_regex.

ZK
Zhemal Khamidun — CPO de Alpina Digital, product manager de AlpinaGPT. Crea productos de IA desde 2019. Hamidun News es un proyecto personal que creció hasta ser un agregador en producción con más de 6.000 lectores.
✦ Hands-On AI Engineering · Hamidun Academy

Build & Ship Production AI Agents Without Boilerplate Code

Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.

Start 72h Free Trial →Vibe-Coding Intensive
¿Qué te parece?
Cargando comentarios…