El pasado sábado 6 de junio tuve la oportunidad de participar como speaker en el GitHub Community Day Perú 2026, donde compartí una charla sobre un tema que sigue siendo una de las causas más frecuentes de incidentes de seguridad: la exposición accidental de credenciales.
Durante la sesión hablamos de herramientas gratuitas que muchos equipos ya tienen disponibles dentro de GitHub, pero que no siempre aprovechan al máximo. Usamos GitHub todos los días para gestionar código, colaborar con nuestros equipos y automatizar despliegues, pero en muchas ocasiones solo utilizamos una pequeña parte de todo lo que la plataforma nos ofrece.
La buena noticia es que GitHub incorpora múltiples funcionalidades de seguridad que pueden ayudarnos a prevenir filtraciones de credenciales, proteger nuestros pipelines y mejorar nuestra postura de seguridad sin necesidad de adquirir herramientas adicionales.
En este artículo recopilo los principales conceptos que vimos durante la charla, junto con una demostración práctica de cómo desplegar una aplicación en AWS sin almacenar una sola credencial permanente.
El problema
Todos lo hemos hecho.
Hardcodear un API key “solo por ahora”, pushear un .env por accidente o compartir un token por Slack para salir de un apuro.
Son errores comunes, pero las consecuencias pueden ser graves: desde una factura inesperada en AWS hasta una filtración de información sensible.
En 2025, De acuerdo al reporte de GitGuardian, GitHub detectó más de 28 millones de secretos expuestos en repositorios públicos. Access Keys de AWS, tokens de GitHub, webhooks de Slack y muchas otras credenciales quedaron visibles para cualquiera que quisiera utilizarlas.
El flujo típico suele verse así:
- Un developer necesita desplegar una aplicación.
- Crea una Access Key y Secret Key.
- Las almacena en un archivo .env o directamente en el código.
- El archivo termina llegando al repositorio.
- Un bot detecta las credenciales y comienza a utilizarlas en cuestión de segundos.
La solución no es simplemente “tener más cuidado”.
La solución es construir mecanismos que hagan mucho más difícil que estos errores lleguen a producción.
GitHub nos ofrece varias capas de protección que pueden ayudarnos precisamente con eso.
Las 5 capas de Seguridad en Github
1. GitHub Secrets
La primera línea de defensa es evitar almacenar información sensible dentro del código.
GitHub Secrets permite guardar valores cifrados que pueden ser consumidos por GitHub Actions durante la ejecución de un workflow.
Características:
- Encriptados mediante libsodium.
- Ocultos automáticamente en los logs.
- No pueden visualizarse nuevamente después de guardarse.
- Disponibles a nivel de repositorio, environment u organización.

Además, los Environments agregan controles adicionales como:
- Aprobaciones manuales para producción.
- Restricciones por branch.
- Wait timers.
- Protección de despliegues críticos.
Si todavía tienes credenciales hardcodeadas en tu código, este debería ser el primer cambio que realices.
2. OIDC con AWS (Zero Credentials)
OIDC es un protocolo de autenticación que permite que dos servicios se reconozcan sin compartir credenciales.
Tradicionalmente, muchos pipelines almacenan Access Keys de AWS dentro de GitHub Secrets.
Aunque esto es mejor que hardcodearlas, seguimos dependiendo de credenciales permanentes que pueden ser filtradas o comprometidas.
Con OpenID Connect (OIDC) podemos eliminar completamente ese problema.
¿Cómo funciona?
- GitHub Actions inicia la ejecución del workflow.
- GitHub genera un token JWT temporal.
- AWS valida el token mediante un OIDC Provider.
- AWS verifica que el repositorio tenga permiso para asumir un rol específico.
- AWS entrega credenciales temporales.
- Las credenciales expiran automáticamente
No hay keys. No hay tokens permanentes. Nada que pueda leakearse.
Paso 1 — Crear el OIDC Provider en IAM:
Provider URL: token.actions.githubusercontent.com
Paso 2 — Crear un IAM Role con trust policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::ACCOUNT_ID:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:MI-ORG/MI-REPO:*"
}
}
}
]
}
La condición StringLike es clave: solo TU repo puede asumir este rol. Si alguien forkea tu repo, no puede deployar.
Paso 3 — Usar en el workflow de Github Actions:
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.AWS_ROLE_ARN }}
aws-region: us-east-1
Eso es todo. Cero secrets de AWS en GitHub.
3. Secret Scanning
Incluso con buenas prácticas, los errores siguen ocurriendo.
Por eso GitHub incorpora Secret Scanning.
Esta funcionalidad analiza automáticamente los commits buscando patrones asociados a credenciales conocidas.
Actualmente puede detectar más de 200 tipos de secretos pertenecientes a más de 100 proveedores.
Ejemplo: AWS, GitHub, Slack, Stripe, Twilio, npm, etc.
Para habilitarlo:
Settings → Code security and analysis → Secret scanning → Enable
Cuando GitHub detecta una credencial:
- Genera una alerta.
- Muestra exactamente dónde se encuentra.
- En algunos casos coordina la revocación automática con el proveedor.
Es una capa reactiva, pero extremadamente útil.
4. Push Protection
Mientras Secret Scanning detecta problemas después del commit, Push Protection intenta detenerlos antes.
Cuando GitHub detecta una credencial durante un push, simplemente bloquea la operación.
El secret nunca llegó al repo. Nunca se expuso. Protección proactiva.
Para habilitarlo:
Settings → Code security and analysis → Push protection → Enable
5. Dependabot
La seguridad no se limita únicamente a las credenciales.
Muchas vulnerabilidades provienen de dependencias desactualizadas.
Cuando se publica un CVE crítico que afecta una librería utilizada por nuestro proyecto, Dependabot puede:
- Detectar la vulnerabilidad.
- Generar una alerta.
- Crear automáticamente un Pull Request con la actualización.
Configuración (.github/dependabot.yml):
version: 2
updates:
- package-ecosystem: "npm"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
Además de dependencias de aplicación, Dependabot también ayuda a mantener actualizadas las GitHub Actions utilizadas por nuestros pipelines.
Demo: Deploy completo sin credenciales
Para demostrar cómo funcionan varias de estas capas trabajando juntas, preparé una aplicación sencilla que lee un secreto desde una variable de entorno y lo muestra en una página web.
El código relevante:
const SECRET_MESSAGE = process.env.SECRET_MESSAGE || 'No secret configured'
La aplicación no conoce el valor del secreto.
Simplemente espera encontrar una variable de entorno durante la ejecución.
La demostración consistió en desplegar esta aplicación en Amazon ECS Fargate, utilizando GitHub Actions para automatizar todo el proceso y OIDC para autenticarnos en AWS sin necesidad de almacenar Access Keys permanentes.
El flujo:
GitHub Secret (SECRET_MESSAGE)
↓
GitHub Actions (OIDC → sin AWS keys)
↓
Build Docker image → Push a ECR
↓
Update ECS Task Definition (inyecta el secret)
↓
Deploy a ECS Fargate
↓
App muestra el secret
Resultado: El secret se muestra en la app, pero si buscas en todo el repositorio, no lo vas a encontrar. Se inyecta en runtime a través de la Task Definition de ECS. Nunca existió en el código fuente.
Qué puedes hacer hoy
Si te llevas algo de este artículo, que sea esto:
Habilita Push Protection: Protección inmediata contra leaks accidentales.
Migra de AWS access keys a OIDC: Eliminas el riesgo más grande de tu pipeline.
Agrega
dependabot.yml: Un archivo y tus dependencias se mantienen actualizadas automáticamente.Mueve secrets hardcodeados a GitHub Secrets: Revisa tu código, busca tokens hardcodeados, y muévelos.
Conclusión
La seguridad de credenciales no tiene que ser complicada.
GitHub nos proporciona múltiples capas de protección que abarcan desde la prevención de errores humanos mediante Push Protection, hasta la detección de credenciales expuestas con Secret Scanning y la eliminación completa de credenciales permanentes mediante OIDC.
La principal reflexión que quise transmitir durante mi charla en el GitHub Community Day Perú 2026 es que muchas veces utilizamos GitHub todos los días, pero no aprovechamos todo el potencial que nos ofrece en materia de seguridad.
Con unas pocas configuraciones podemos reducir significativamente el riesgo de exposición de credenciales y fortalecer nuestros pipelines sin añadir complejidad innecesaria.
Las diapositivas utilizadas para la presentación están disponibles en: https://speakerdeck.com/bnktch13/seguridad-en-github-para-devops
Y el código completo del ejemplo utilizado durante la demostración está disponible en: https://github.com/BnkTCh/secure-deploy-demo
Te invito a explorarlo, probarlo y adaptarlo a tus propios proyectos.
Y si estuviste presente en la charla durante el GitHub Community Day Perú 2026, gracias por acompañarme y por todas las preguntas y conversaciones que hicieron la sesión aún más interesante.










Top comments (0)