39 millones de secretos filtrados en GitHub. El tuyo puede ser el siguiente.

| Última modificación: 4 de mayo de 2026 | Tiempo de Lectura: 5 minutos
Premios Blog KeepCoding 2025

Co-Fundador de KeepCoding

5 minutos. Eso es lo que tardaron.

Un investigador de seguridad publica un access key de AWS en un repositorio público de GitHub. Lo hace a propósito, como experimento.

Cinco minutos después, alguien ya lo estaba usando para minar criptomonedas.

Cinco. Minutos.

Hay bots escaneando GitHub 24/7 buscando exactamente eso: credenciales expuestas. Y son rápidos. Mucho más rápidos que tú dándote cuenta de que la has cagado.

Las cifras dan miedo

Según GitHub, en 2024 se filtraron 39 millones de secretos en repositorios públicos. Un 67% más que el año anterior.

GitGuardian, que se dedica a escanear exactamente esto, encontró 23.7 millones de secretos nuevos solo en repos públicos. Y lo peor: el 70% de los secretos detectados en 2022 seguían activos en 2024.

Dos años después. Todavía funcionando. Esperando a que alguien los use.

No es solo gente random

Toyota tuvo credenciales de AWS expuestas en GitHub que daban acceso a su sistema de telemática de vehículos. Pearson perdió datos porque alguien dejó un token de GitLab en un fichero de configuración. Otelier, una empresa de hostelería, vio cómo exfiltraban 8TB de datos de S3 por credenciales expuestas en Bitbucket.

Esto no le pasa solo al becario. Le pasa a empresas del Fortune 500.

El clásico: «Solo es mi proyecto personal»

Ya, claro.

El problema es que ese proyecto personal tiene el mismo API key de OpenAI que usas en producción. O el token de tu bot de Telegram. O las credenciales de tu base de datos de staging que, oh sorpresa, tiene datos reales porque «así es más fácil probar».

Y un día haces git push sin pensar. O cambias el repo de privado a público porque quieres enseñárselo a alguien. O GitHub tiene un bug y expone repos privados temporalmente (ha pasado).

Y entonces descubres que tu factura de AWS ha pasado de 20€ a 2.000€. En una noche.

«Pero lo borré inmediatamente»

Otro clásico.

Git es un sistema de control de versiones. Su trabajo literal es recordar todo lo que ha pasado. Borrar el commit no borra el secreto del historial. Hacer force push no lo borra de los forks. Y definitivamente no lo borra de los bots que ya lo copiaron.

Una vez que un secreto toca un repo público, está comprometido. Punto. Hay que rotarlo.

La pirámide del desastre

Así es como suele evolucionar la gestión de secretos en un proyecto típico:

Nivel 1: El infierno

# config.py
AWS_KEY = "AKIAIOSFODNN7EXAMPLE"
AWS_SECRET = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"

Directamente en el código. Commiteado. En producción. No te rías, esto existe.

Nivel 2: El purgatorio

# .env (en .gitignore, supuestamente)
AWS_KEY=AKIAIOSFODNN7EXAMPLE
AWS_SECRET=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

Mejor, pero ese .env acaba en un backup, en un zip que mandas por Slack, en un disco duro que vendes en Wallapop…

Nivel 3: El limbo

# Secretos en variables de entorno del sistema
export AWS_KEY=...

Vale, pero ¿dónde los guardas? ¿En un post-it? ¿En un fichero secrets.txt en el escritorio? ¿En un mensaje de Slack a ti mismo?

La solución: secretos fuera del código, fuera del disco

Después de ver cómo casi la lío unas cuantas veces, decidí centralizar todo en 1Password y usar su CLI para inyectar secretos cuando haga falta.

El concepto es simple: 1. Los secretos viven en 1Password, no en mi disco 2. El código tiene referencias a los secretos, no los secretos en sí 3. Los secretos se inyectan en tiempo de ejecución

El patrón .env.template + op inject

En cada proyecto, en lugar de un .env con valores reales, tengo un .env.template con referencias:

# .env.template - ESTO SÍ VA A GIT
# Regenerar con: op inject -i .env.template -o .env.local

OPENAI_API_KEY=op://FRR DEV/OpenAI/api-key
SUPABASE_URL=op://FRR DEV/Supabase Personal/url
SUPABASE_SERVICE_KEY=op://FRR DEV/Supabase Personal/service-key
DATABASE_URL=postgres://localhost/mydb  # valores no secretos van directo

Cuando necesito el .env real, ejecuto:

op inject -i .env.template -o .env.local

1Password lee las referencias op://, las resuelve con los valores reales, y genera el fichero. El .env.local está en .gitignore, nunca toca git.

¿Qué gano con esto?

1. Un solo sitio para todos los secretos

Antes tenía credenciales repartidas en ficheros .env de 15 proyectos, variables de entorno en .bashrc, tokens en mensajes de Slack, y alguno que otro en un post-it (no me juzgues).

Ahora todo está en un vault de 1Password. Un sitio. Encriptado. Con historial de cambios.

2. Rotación de secretos trivial

Antes: cambiar un API key significaba buscarlo en todos los proyectos, actualizar ficheros, rezar para no olvidarme de ninguno.

Ahora: actualizo el valor en 1Password, ejecuto op inject en cada proyecto, listo.

3. El código documenta qué necesita

El .env.template es documentación viva. Cualquiera que clone el proyecto sabe exactamente qué secretos necesita. Solo tiene que tenerlos en su propio 1Password (o pedírtelos).

4. Imposible commitear secretos por accidente

El fichero que va a git solo tiene referencias op://. Aunque hagas git add . sin pensar, no estás exponiendo nada.

5. Sincronización entre máquinas gratis

¿Mac nuevo? Instala 1Password, haz login, op inject. Todos tus secretos disponibles sin copiar ficheros ni mandar nada por Slack.

Para el día a día: lazy loading en Fish

Para comandos que necesitan credenciales (como oco para commits con IA), tengo esto en mi config de Fish:

function oco
    if not set -q OPENAI_API_KEY
        set -gx OPENAI_API_KEY (op read "op://FRR DEV/OpenAI/api-key")
    end
    command oco $argv
end

La primera vez que ejecuto oco, me pide Touch ID. A partir de ahí, la variable está cargada en la sesión.

El único inconveniente

Sí, hay uno: tienes que autorizar con Touch ID o contraseña de vez en cuando.

Lo he optimizado configurando 1Password para que recuerde autorizaciones 24 horas y solo se bloquee al dormir el Mac. Pero sí, de vez en cuando te toca poner el dedo.

Es un pequeño precio a pagar por no aparecer en las estadísticas de GitGuardian.

No es opcional

Mira, entiendo que todo esto suena a paranoia. «A mí no me va a pasar». «Es solo un proyecto pequeño». «No tengo nada importante».

Pero piensa en esto: ¿tienes algún API key de pago? ¿OpenAI? ¿AWS? ¿Cualquier servicio que cobre por uso?

Entonces tienes algo que alguien puede explotar.

Y los bots no descansan. No distinguen entre el proyecto de una startup y los deberes de programación de un estudiante. Escanean todo, prueban todo, explotan todo.

39 millones de secretos filtrados en 2024. El 70% de los de 2022 siguen activos.

La gestión correcta de secretos no es una best practice. Es higiene básica.

Como lavarte las manos. No lo haces porque sea divertido. Lo haces porque la alternativa es coger una infección.

Tus secretos en git son una infección esperando a ocurrir.


Resumen ejecutable:

  1. Instala 1Password y su CLI (brew install 1password-cli)
  2. Crea un vault para desarrollo
  3. Migra tus secretos de ficheros .env al vault
  4. Crea .env.template con referencias op://
  5. Añade .env.local a .gitignore
  6. Regenera con op inject cuando haga falta

Y ya está. Treinta minutos de setup que te ahorran aparecer en el próximo informe de GitGuardian.

Tus credenciales de AWS te lo agradecerán.


Actualización: Después de implementar todo esto, descubrí que 1Password me pedía Touch ID demasiado. Tanto que empecé a aprobar sin mirar. Eso tiene un nombre en seguridad y no es bueno. Lee Cuando la seguridad te pide permiso tantas veces que dejas de leer para ver cómo lo resolvimos.


Read this article in English.

Noticias recientes del mundo tech


¡CONVOCATORIA ABIERTA!

Desarrollo de apps móviles ios & Android

Full Stack Bootcamp

Clases en Directo | Profesores en Activo | Temario 100% actualizado

Descárgate también el informe de tendencias en el mercado laboral 2026.

Fórmate con planes adaptados a tus objetivos y logra resultados en tiempo récord.
KeepCoding Bootcamps
Resumen de privacidad

Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.