Claude Code guarda en texto plano, en .claude/settings.local.json, la contraseña o el token de cualquier comando que aprobaste con “Yes, and don’t ask again”. Si ese archivo llegó a un repo público, cualquiera puede leerlo: Apiiro Research revisó las 104 185 copias públicas del archivo en GitHub y encontró un secreto real en 1122 de ellas, poco más del 1 por ciento. Sumando el historial de git, los archivos de configuración compartidos y las transcripciones de agentes, el total llega a 2539 secretos distintos en 1994 repos.
Estado al 8 de noviembre de 2026: Anthropic no ha publicado ninguna corrección ni ha indicado en qué versión llegaría. Las cifras del estudio corresponden a una foto de las ramas por defecto tomada el 2 de noviembre de 2026.
El estudio, de Shmulik Cohen y Matan Giladi, se publicó el 5 de noviembre de 2026. Las comprobaciones de esta nota toman unos minutos por repo y no dependen de que las cifras de Apiiro sean exactas.
¿Claude Code guarda mis contraseñas en settings.local.json?
Sí, a través del aviso de aprobación. Pídele a Claude Code que revise por qué falla el login en staging o que ejecute una migración, y el comando que propone lleva la credencial que tenga tu configuración: una cadena de conexión, un PGPASSWORD=, un sshpass -p o una cabecera bearer. Sin ella, el comando no funciona.
Claude Code pregunta antes de ejecutar un comando de shell. Si eliges “Yes, and don’t ask again”, según la propia documentación de Anthropic, guarda esa aprobación como una regla allow en .claude/settings.local.json, en la raíz del repositorio de git. La regla es el comando tal como aparece en la opción que elegiste. Cuando esa opción muestra la línea de comando completa, el secreto que contiene entra al archivo con ella.
Apiiro afirma que es un comportamiento de Claude Code, no del modelo: lo reprodujo con Opus 5.5 y con Fable 5.1. Y cuanto más tiempo llevas aprobando con “don’t ask again”, peor: uno de cada diez archivos de más de 8 KB tenía un secreto real, frente a menos de uno de cada 500 entre los de menos de 500 bytes.
Esto es lo que encontró Apiiro, por tipo:
| Tipo | Cantidad |
|---|---|
| Contraseñas de bases de datos | 379 |
| Claves service-role de Supabase | 122 |
| Tokens de cuenta de Supabase (controlan todos los proyectos de la cuenta) | 103 |
Accesos SSH, algunos como root con sshpass |
43 |
| Tokens de GitHub, GitLab y npm | 42 |
| Claves de AWS | 23 |
| Claves privadas | 6 |
Son 1379 secretos distintos solo en las copias actuales de settings.local.json. Hay 63 organizaciones afectadas, desde grupos de estudiantes hasta startups, agencias y proveedores establecidos. Entre los casos: una contraseña de producción de Postgres en Azure, un token de producción de Square y la contraseña de propietario de la base de datos de una app de historias clínicas.
¿Cómo saber si Claude Code filtró mis secretos a GitHub?
Con cuatro comprobaciones, siguiendo el procedimiento de Apiiro. Reemplaza tu-org por tu organización o tu usuario de GitHub.
1. ¿El archivo está público ahora mismo?
Busca el archivo en el código de tu organización en GitHub:
path:.claude/settings.local.json org:tu-org
Para una cuenta personal, usa user:tu-usuario en lugar de org:. Repite la búsqueda con path:.claude/settings.json: es el archivo de configuración compartido que los equipos suben a propósito, y Apiiro encontró secretos reales en 298 de las 76 011 copias públicas que revisó. La búsqueda de código muestra los archivos como están hoy; el historial es el paso 3.
2. ¿Git está rastreando el archivo en este repo?
Desde dentro de cada repo:
git ls-files .claude/settings.local.json
Si imprime la ruta, git está rastreando el archivo y cada push lo publica.
3. ¿Se subió alguna vez al historial de git?
git log --all --oneline -- .claude/settings.local.json
Cualquier resultado significa que el archivo está en el historial, aunque hoy ya no exista en el directorio de trabajo. Para ver qué contenía cada versión, añade -p:
git log --all -p -- .claude/settings.local.json
Esto importa más de lo que parece. Apiiro encontró 734 secretos que solo existen en versiones anteriores del archivo, en 509 repos, casi siempre porque alguien borró el archivo y dio el problema por resuelto. Además, 211 forks de 74 repos tienen los mismos secretos.
4. ¿Qué contienen tus copias locales?
La mayoría de estos archivos nunca llegan a GitHub, pero siguen siendo un almacén de credenciales en JSON plano dentro de tu laptop. Encuentra todas las copias:
find ~ -path '*/.claude/settings.local.json'
Busca en todas partes, no solo en la raíz de los repos: antes de la versión 2.1.211, Claude Code guardaba el archivo en el directorio desde el que lo iniciabas, así que puede haber copias antiguas en subdirectorios. Abre cada una y lee su lista allow: cada entrada es un comando que aprobaste, con todo lo que escribiste en él. Dentro de Claude Code, /permissions también muestra todas las reglas y de qué archivo viene cada una.
Encontré un secreto: ¿cómo lo roto y lo saco de git con git rm --cached?
Primero rota, después limpia. Borrar el archivo no limpia el historial de git, los forks ni los clones, así que la credencial hay que darla por quemada.
- Rota todas las credenciales que el archivo haya tenido alguna vez, incluidas las que solo aparecen en commits antiguos del paso 3.
- Deja de rastrear el archivo y mantenlo fuera para siempre:
Después añadegit rm --cached .claude/settings.local.json.claude/settings.local.jsonal.gitignoredel propio repo. - Borra todas las reglas que contengan un secreto, también en los archivos que nunca se subieron.
- Deja de escribir secretos dentro de los comandos. Refiérete a ellos como variables de entorno desde tu gestor de secretos, para que la regla guarde
$DB_URLy no la contraseña. - Aprueba patrones, no comandos literales. Una regla como
Bash(npm run *)cubre todos los scripts de npm y no guarda argumentos. La documentación de Anthropic acepta también la forma anteriorBash(npm run:*)como equivalente; el diálogo de permisos escribe la forma con espacio.
¿Claude Code no excluye ya este archivo de git?
Lo intenta, y ahí está justamente el hueco. Según la documentación de settings de Anthropic, la primera vez que Claude Code escribe .claude/settings.local.json dentro de un repo de git, añade **/.claude/settings.local.json a tu archivo de exclusiones global de git. Eso cubre el caso común en tu máquina.
No cubre:
- una carpeta que se convierte en repo después de que se creó el archivo;
- un clon en otra máquina o en la laptop de alguien del equipo;
- un archivo que alguien ya subió;
- un archivo que creaste a mano: la documentación te pide que lo añadas tú al
.gitignore.
Como la exclusión vive en tu configuración global de git y no en el .gitignore del repo, nada viaja con el proyecto para protegerlo.
Las dos partes leen la evidencia de forma distinta. Boris Cherny, que lidera Claude Code, escribió en Hacker News que en estos casos los archivos se crearon a mano y se subieron a mano. Apiiro informa que en 539 de los 1105 repos con un secreto real que rastreó, un commit coautorado por Claude modificó el archivo, con modelos desde Sonnet 4.5 hasta Opus 5.5. Las dos cosas pueden ser parcialmente ciertas; en cualquier caso, la solución de tu lado es la misma.
¿Por qué gitleaks y TruffleHog no detectaron estas contraseñas?
Porque los secretos que se filtran aquí casi nunca tienen forma de clave. Apiiro ejecutó gitleaks y TruffleHog sobre los 104 185 archivos. De los 1122 que tenían un secreto real, gitleaks marcó 564 y TruffleHog 643; 215 no los detectó ninguno de los dos.
Los escáneres de secretos (secret scanning) buscan formatos de clave: un prefijo de proveedor, una cadena larga y aleatoria. Una contraseña después de PGPASSWORD=, sshpass -p o mysql -p, o dentro de una cabecera bearer en un curl, es una palabra cualquiera en una línea de comando cualquiera. El mismo patrón aparece en todos los lugares donde un agente registra lo que ejecutó: transcripciones, archivos de memoria, notas de traspaso.
Ese hueco también importa en tu laptop. En septiembre de 2025, el gusano de npm Shai-Hulud descargaba TruffleHog y lo ejecutaba sobre los archivos de sus víctimas: el mismo escáner que ya detecta 643 de estos archivos.
¿Qué deberían cambiar los equipos de seguridad?
Estas son las recomendaciones de Apiiro para equipos, y valen para cualquier agente de programación, no solo para Claude Code:
- Trata las carpetas de agentes como portadoras de secretos, igual que
.env:.claude/,.cursor/,.gemini/,.specstory/y los archivos de memoria de agentes, tanto en las laptops como en los repos. - Inclúyelas en el escaneo de secretos de pre-commit y de CI, con historial incluido, y comprueba que el escáner detecte contraseñas dentro de comandos (
PGPASSWORD=,sshpass -p,mysql -p, cabeceras bearer), no solo formatos de clave de proveedor. - Añade
.claude/settings.local.jsona las plantillas de.gitignorede tu organización. - Prioriza las credenciales que van junto a un host público: son las que dan acceso.
Apiiro también encontró el mismo hábito en archivos de otros agentes: secretos reales en 120 transcripciones de chat de agentes en 87 repos (exportaciones de .specstory, aider y Cursor) y en la configuración de aprobación automática de Copilot en VS Code en 9 repos. Pero, según su lectura de la documentación de cada uno, Claude Code es el único de 16 agentes de programación que escribe por defecto el comando aprobado completo en un archivo del proyecto.
¿Qué ha dicho Anthropic?
Apiiro compartió la investigación con Anthropic antes de publicarla. En su comentario en Hacker News, Cherny dijo que Claude Code no ha eliminado históricamente los secretos de estas reglas (secret scrubbing) y que el equipo está buscando cómo evitarlo; Apiiro añade que el escaneo básico de secretos es uno de los enfoques que Anthropic va a prototipar. Cherny recomendó además dos cosas:
- El modo auto en lugar de las reglas de permisos. En el modo auto, un clasificador en segundo plano revisa las acciones antes de que se ejecuten, así que no vas acumulando una lista
allow. Según la documentación de Anthropic,defaultModecon el valorautosolo tiene efecto desde tu configuración de usuario (~/.claude/settings.json) o desde la configuración administrada, no desde la del proyecto ni desde la local. - El escaneo de secretos en tu plataforma de control de código, uses el agente que uses.
Al momento de publicar esta nota, Anthropic no había lanzado ninguna corrección ni indicado una versión. Los usuarios han reportado este mecanismo en issues de GitHub desde agosto de 2025 (#5544, #11982, #13106, #91270); según Apiiro, ninguno recibió respuesta de Anthropic y tres se cerraron automáticamente por inactividad o como duplicados.
¿Qué tan confiables son los números de Apiiro?
Sólidos en el mecanismo, que la propia documentación de Anthropic confirma, con límites que conviene conocer:
- Apiiro vende productos de seguridad de secretos y ASPM, así que tiene un interés comercial en el hallazgo.
- “Secreto real” no significa validado. No se probó ninguna credencial ni se contactó ningún host. Significa un valor que coincide con un formato de proveedor o que está junto a un host público. Solo una organización confirmó que su clave estaba activa.
- La clasificación combinó reglas con un revisor LLM independiente que trabajó con una rúbrica escrita; un valor contó solo cuando ambos coincidieron.
- La cifra del historial es un piso, y gitleaks y TruffleHog se ejecutaron sin sus modos de verificación.
- La comparación de 16 agentes sale de leer documentación, no de pruebas.
- Las cifras son una foto de las ramas por defecto del 2 de noviembre de 2026. Las organizaciones se describen por sector y no por nombre: es lo responsable, pero significa que ningún caso se puede verificar de forma independiente.
Los trabajos anteriores apuntan en la misma dirección: ironPeak encontró el archivo en su propio repo en febrero de 2026, y Lakera encontró credenciales en 33 de estos archivos dentro de 30 paquetes de npm en abril.
¿Qué es Claude Code?
Claude Code es la herramienta de programación agéntica de Anthropic: funciona en la terminal, en IDEs y en la app de escritorio de Claude, lee tu repo, edita archivos y ejecuta comandos de shell en tu nombre, pidiendo aprobación salvo que una regla o un modo diga lo contrario. Ese sistema de aprobaciones es el que genera settings.local.json, y es la razón de que un comando que escribe el agente pueda llevar, y dejar registrada para siempre, cualquier credencial que haya visto.
¿Y tú? ¿Qué es lo primero que revisas cuando clonas un repo que trae una carpeta .claude/?
- Con “Yes, and don’t ask again” casi siempre
- Escribo mis propias reglas con patrones
- Uso el modo auto
- Prefiero otra opción (cuéntanos cuál)
Comenta abajo o, si este artículo te llegó por correo, responde directamente al email: tu respuesta se publica aquí.
Relacionado: ¿Claude Code envía tu correo a las webs que visita? Qué pasó con el User-Agent y cómo comprobar si estás protegido
