Cómo proteger tu pipeline de CI/CD

Tue Aug 25 2026

Cómo proteger tu pipeline de CI/CD

Pero el 14 de marzo de 2025, un atacante redirigió cada etiqueta de versión del incidente de tj-actions/changed-files, desde v1 hasta v45.0.7, a un commit malicioso. La acción se utilizaba en más de 23.000 repositorios. Su payload escaneó la memoria del runner e imprimió secretos en los logs del workflow.

Buscar CVE no detectará paquetes maliciosos sin ningún CVE. Esos paquetes pueden comprometer los sistemas que compilan, prueban o publican tu software. Tratar YAML como una configuración inofensiva es un error de categoría. Un pipeline es infraestructura de producción, independientemente de si tu organización considera su YAML crítico para la seguridad.

La respuesta corta: fija las acciones de terceros, establece permisos explícitos, reemplaza los secretos de cloud de larga duración por OIDC con confianza limitada, bloquea las dependencias y genera SBOM; después firma y verifica los artefactos de release.

Por eso, esta guía utiliza el Secure Software Development Framework (SSDF) de NIST como mapa basado en riesgos. Sigue la confianza desde el código fuente hasta el build, el artefacto y el despliegue; después te ofrece un modelo de ownership y un orden de operaciones de cinco controles.

Security controls mapped across a CI/CD pipeline from source to deployment.

En este artículo

Los atacantes pueden entrar antes de que exista un CVE

Empieza en un lugar distinto del informe de CVE. Este te informa sobre fallos conocidos en componentes. No puede establecer la confianza en tu workflow, runner, credenciales o proceso de release.

No usaría el informe de Phoenix Security sobre 59 campañas y 657 paquetes maliciosos como una predicción. Su punto útil es más limitado: las entradas maliciosas pueden estar libres de CVE conocidos.

Y asume que un atacante puede alterar una acción upstream, enviar código desde un fork, comprometer a un publisher de dependencias o cambiar la configuración de CI. Detén ese código antes de que obtenga la siguiente credencial o privilegio de release.

Tres rutas merecen un tratamiento separado:

  • Inyección en el pipeline: el código del workflow, los reusable workflows, las referencias a acciones, la configuración de la interfaz de usuario o las variables de entorno hacen que el runner ejecute instrucciones controladas por el atacante.
  • Compromiso de dependencias: un paquete malicioso entra a través de un publisher comprometido, dependency confusion o un rango de versiones que posteriormente se resuelve de forma diferente.
  • Compromiso del entorno del desarrollador: las credenciales robadas o el código alterado se originan en una estación de trabajo, editor, herramienta local o token antes de que el código llegue al repositorio.

Estas rutas convergen en el runner. Este ejecuta comandos y recibe credenciales. Resuelve dependencias y produce artefactos. Exporta la configuración del dashboard, revisa los cambios en las variables de entorno y expira las credenciales del runner; el YAML versionado no es todo el pipeline.

Tu registro mínimo de auditoría del pipeline debe capturar el contexto de ejecución. Registra los comandos ejecutados, los secretos a los que se accedió y los artefactos modificados. Incluye la identidad del workflow, el commit, el runner y la decisión de despliegue. Los eventos del repositorio por sí solos dejan demasiados datos sin registrar.

Usa SSDF para elegir controles, no para rellenar una hoja de cálculo

NIST publicó SP 800-218, SSDF v1.1 en febrero de 2022. Sus cuatro grupos de prácticas son:

  • Prepare the Organization (PO): establecer personas, políticas, procesos y entornos de desarrollo seguros.
  • Protect the Software (PS): proteger el código fuente, las dependencias, los sistemas y las credenciales.
  • Produce Well-Secured Software (PW): compilar, probar, verificar y publicar software de forma segura.
  • Respond to Vulnerabilities (RV): identificar, evaluar, remediar y comunicar vulnerabilidades.

NIST describe SSDF como una base de planificación y no como una hoja de cálculo de compliance:

“SSDF proporciona una base para planificar e implementar un enfoque basado en riesgos, en lugar de una checklist que seguir.”

Esa distinción determina cómo utilizas aquí el framework. PO cubre el ownership y la preparación del entorno, incluidas las excepciones. PS cubre el código fuente, las acciones, las dependencias, los runners y las credenciales. PW cubre la evidencia del build y del release. RV cubre el análisis de impacto, la remediación y la recuperación.

El anuncio de SSDF v1.2 de NIST denomina a la versión 1.2 un borrador público inicial publicado el 17 de diciembre de 2025. Trata v1.2 como guía preliminar; construye tu baseline sobre la publicación final de v1.1. NIST también anunció directrices DevSecOps activas en marzo de 2026 que anteriormente estaban abiertas a comentarios.

Usa el framework como mapa y después incorpora guardrails en tu pipeline.

Protege el código fuente y el workflow antes de escanear el código

Exige revisión para los archivos de workflow, la configuración de despliegue, los reusable workflows y cualquier archivo que pueda cambiar el comportamiento de ejecución o de release. Los commits firmados pueden ayudar a establecer la autoría, aunque implican trabajo de gestión de claves. Dales prioridad después de los permisos y las referencias a acciones, salvo que tu organización ya gestione correctamente la firma.

Establece explícitamente los permisos de GitHub Actions:

permissions:
  contents: read

Usa {} cuando un job no necesite permisos del repositorio. Concede un scope de escritura solo al job que lo necesite. Un job que comenta en pull requests podría recibir pull-requests: write. Un job de test no debería recibir ninguno por defecto.

En GitHub, un GITHUB_TOKEN limitado a contents: read no puede subir contenido al repositorio ni crear releases mediante ese token. Audita el job para detectar otras credenciales y accesos heredados.

Ten cuidado con pull_request_target. Se ejecuta en el contexto del repositorio base y puede recibir sus permisos y secretos. Hacer checkout del commit head de un fork y ejecutar sus scripts proporciona al autor del fork acceso de confianza.

Ejecuta el código de los forks en un entorno restringido sin secretos del repositorio. Si un job privilegiado debe consumir su salida, trata los artefactos como bytes no confiables: valida su formato antes del procesamiento privilegiado, nunca ejecutes scripts incrustados y nunca los utilices para construir comandos privilegiados.

En términos de SSDF, esto corresponde a PS porque los controles protegen el código fuente y las entradas de ejecución antes de que comience la producción. PO proporciona la política de revisión, los permisos predeterminados y el responsable de las excepciones.

Comprar un scanner más grande antes de controlar estas rutas es hacerlo al revés.

Haz que cada build resuelva el código que pretendías

Fija las acciones de terceros a commit SHA revisados:

# Illustrative abbreviated SHA; production requires the verified full SHA
- uses: tj-actions/changed-files@0e58ed8

Un workflow de producción debería utilizar el SHA completo de 40 caracteres del commit:

- uses: tj-actions/changed-files@<verified-full-40-character-sha>

El valor abreviado 0e58ed8 sirve para explicar la diferencia entre una etiqueta mutable y una referencia a un commit. No es un pin de producción completo.

Una etiqueta como @v45 es un puntero mutable. Como explica el análisis técnico de Safeguard:

“Una etiqueta de git es solo un puntero mutable, y cualquiera con acceso de push al repositorio upstream —incluido un atacante que haya comprometido la cuenta de un maintainer o un token de publicación al estilo npm— puede moverla a otro commit en cualquier momento.”

Fijar las acciones de terceros a commit SHA inmutables es uno de los controles menos llamativos y de mayor valor en la seguridad de CI/CD. Una etiqueta flotante es una decisión de confianza que tomas en cada ejecución.

Los pins SHA generan trabajo de mantenimiento. Usa Dependabot o Renovate para proponer actualizaciones revisadas. Inspecciona el cambio del commit, las notas de release y los cambios de permisos antes de hacer merge. Volver a etiquetas flotantes por comodidad anula el control.

Las dependencias necesitan la misma disciplina. Haz commit de package-lock.json y poetry.lock. Haz commit también de go.sum. Verifica las firmas de los paquetes cuando el ecosistema las admita. Supervisa cambios inesperados en el árbol de dependencias. No trates un rango como ^1.2.3 de npm como un control suficiente. Utiliza en CI el modo de instalación del package manager que obliga a usar el lockfile y revisa cada cambio en el lockfile.

En términos de SSDF, el pinning SHA y la verificación de dependencias protegen las entradas del software bajo PS. El build resultante y reproducible respalda PW.

Usa OIDC para el acceso a cloud, con una política de confianza limitada

Las credenciales de cloud almacenadas pueden seguir siendo válidas hasta que alguien las rote o revoque. OpenID Connect (OIDC) cambia la forma en que el workflow se autentica: el job intercambia un JWT emitido por GitHub por credenciales temporales del proveedor. El JWT no concede por sí mismo acceso a cloud.

Un job podría declarar:

permissions:
  contents: read
  id-token: write

El proveedor de cloud evalúa entonces una política de confianza. Restringe esa política por repositorio y rama. Añade el entorno de despliegue o claims equivalentes cuando corresponda. Un token de un repositorio arbitrario nunca debería poder asumir tu rol de producción.

Las credenciales suelen expirar aproximadamente en una hora, aunque la duración exacta depende del proveedor y de la configuración. OIDC es preferible a los secretos de cloud de larga duración, pero no es magia: una política de confianza mal delimitada sigue convirtiendo las credenciales temporales en credenciales potentes.

Aplica el least privilege dos veces. Limita los permisos del job de CI y después limita las acciones y recursos del rol de cloud. Revisa ambos cuando cambie un workflow.

El masking no es un control de acceso. Un step comprometido aún puede intentar exfiltrar cualquier secreto disponible para su proceso, y el masking de cadenas exactas puede no detectar salidas codificadas, divididas, reformateadas o que no aparezcan en los logs.

En términos de SSDF, esto es PS porque protege las credenciales y los sistemas que las utilizan. PO determina quién revisa la política de confianza y cómo expiran las excepciones.

Trata el artefacto como evidencia que puedes verificar

Un release defendible contiene evidencia sobre su salida. Genera una SBOM de software CycloneDX o SPDX en cada build. Una SBOM registra los componentes, incluidas las dependencias transitivas, para que los equipos de respuesta puedan identificar los artefactos de producción afectados después de la divulgación de una vulnerabilidad.

NIST SSDF v1.1 añadió PS.3.2 para los datos de provenance. La provenance vincula un artefacto con su commit de origen, workflow y entorno de build. Una firma establece la integridad únicamente dentro de un límite de confianza de clave y política.

ControlPregunta respondidaRespuesta recomendada
SBOM¿Dónde está desplegada esta dependencia?Poner en cuarentena o reconstruir los artefactos afectados.
Firma¿Este artefacto fue producido por un proceso autorizado?Rechazar un artefacto que no pueda verificarse.
Provenance¿Qué código fuente y build lo produjeron?Investigar o reconstruir a partir de entradas confiables.

Estos controles son el mapeo operativo de Blackhawk de PW y RV: producir evidencia del release y después utilizarla para evaluar el impacto y responder.

El despliegue debe verificar el artefacto aprobado

Los checks durante el build pierden su valor si el despliegue puede seleccionar una salida arbitraria. Aplica las reglas de despliegue como código.

Una política útil exige un artefacto firmado y un repositorio y rama de origen aprobados. También comprueba la identidad del workflow y los checks requeridos. Almacena el digest y el commit de origen como metadata firmada. Incluye la identidad del workflow y los resultados de los checks en un registro de release inmutable que la política de despliegue pueda leer.

Utiliza esta secuencia:

  1. Compila el artefacto y genera su SBOM y provenance.
  2. Fírmalo mediante el proceso de release autorizado.
  3. Exige policy checks antes de la promoción.
  4. Verifica la firma, el digest, la provenance y los checks requeridos durante el despliegue.
  5. Confirma que el artefacto en ejecución coincide con el artefacto aprobado.
  6. Registra la identidad del workflow, el commit y los SHA de las acciones. Registra la identidad del runner y los claims de las credenciales. Añade el digest del artefacto, los comandos ejecutados, el acceso a secretos, las modificaciones del artefacto y la decisión de despliegue.

Separa los privilegios de build y despliegue cuando sea posible; un job de test no debería poseer automáticamente autoridad sobre producción. Para los controles del lado de la nube, consulta cómo asegurar aplicaciones SaaS.

Este es el traspaso de PW a RV: la evidencia del release se convierte en feedback del despliegue y en evidencia de incidentes.

Si solo puedes hacer cinco cosas, hazlas en este orden

Este orden es nuestro criterio operativo, no una clasificación universal medida. El aislamiento del runner, la arquitectura de producción y el diseño del release pueden hacer que un elemento suba de prioridad en tu entorno. Tu blast radius depende de tu entorno; mídelo antes de declarar terminado el trabajo.

PrioridadControlPor qué aparece aquíIntención de SSDF
1Fijar las acciones de terceros a commit SHA revisados y automatizar pull requests de actualización.Controla qué código ejecuta cada job antes de que las demás defensas puedan ayudar.PS / PW
2Establecer permisos explícitos de mínimo privilegio para el workflow y cloud.Limita el daño cuando un step o una acción se ve comprometido.PS
3Reemplazar las credenciales de cloud de larga duración por OIDC con confianza limitada.Reduce la duración de las credenciales una vez restringidos los permisos.PS / PO
4Bloquear y verificar las dependencias, y después generar una SBOM para cada build.Hace trazables las entradas del build y proporciona un inventario a los equipos de respuesta.PS / PW / RV
5Firmar y verificar los artefactos de release, con una política de digest y provenance más logs de ejecución.Controla la transición final de la salida del build al despliegue.PW / RV

La quinta fila es un workstream de evidencia del release con tareas de implementación separadas. No confundas la planificación agrupada con un único gate gigantesco.

SAST analiza el código fuente, SCA analiza las dependencias y el secret scanning busca material parecido a credenciales en el código fuente y el historial. Añade container scanning cuando produzca un fallo accionable. No conviertas un scanner en la única razón por la que un release se considera confiable.

Asigna ownership al equipo de plataforma y una vía de excepciones a seguridad

El equipo de plataforma o DevOps debería tener el ownership de las plantillas de workflow, los permisos predeterminados, las actualizaciones de acciones, la configuración de los runners y los policy checks. Seguridad debería definir el baseline, revisar los cambios de alto impacto y gestionar las excepciones.

La aprobación de seguridad para cada edición rutinaria de un workflow es una cola disfrazada de governance. Falla automáticamente ante una acción sin pin, un secreto expuesto, un artefacto no confiable o un cambio en el rol de producción. Reporta los hallazgos de menor confianza sin bloquear el pull request.

Cada excepción necesita un responsable, un motivo, un control compensatorio, una fecha de expiración y una vía de revisión. Una excepción permanente es un cambio no documentado en tu modelo de seguridad.

Los desarrolladores deberían ver el control fallido y su vía de remediación. Reserva la escalación para nuevas acciones privilegiadas, cambios en roles de producción o bypasses deliberados de políticas.

Eso es PO en términos operativos: preparar la organización para que el trabajo de seguridad tenga un lugar en vez de convertirse en una cola.

El código asistido por AI sigue entrando en la misma cadena de confianza

NIST ha finalizado SP 800-218A, un Community Profile de SSDF para Generative AI y Dual-Use Foundation Models. Proporciona contexto de governance para los equipos que utilizan desarrollo asistido por AI; no reemplaza los controles de implementación de CI/CD.

El código generado por AI debería seguir el mismo proceso de branch protection, verificación de dependencias, testing, secret scanning, provenance y revisión que el código escrito por personas. Su origen no establece su seguridad. La evidencia sí.

El problema de los cero-CVE refuerza el punto: el escaneo de vulnerabilidades conocidas no puede establecer la confianza por sí solo. Registra el commit de origen, limita las entradas, prueba el resultado y conserva la evidencia del artefacto.

Mantén medibles las cuatro transiciones de confianza

Define una ruta como un job de workflow junto con las credenciales, referencias a acciones, artefactos y destino de despliegue a los que puede llegar. Haz un inventario de cada ruta con su trigger y sus scopes de token. Registra sus secretos y su rol de cloud. Incluye sus salidas de artefactos y destinos de despliegue.

Controla después las cuatro transiciones. Autoriza el código fuente y limita las entradas del build. Conserva la evidencia del artefacto y verifica el despliegue. SSDF te proporciona el mapa basado en riesgos; el ownership y las condiciones de fallo medibles lo mantienen activo. Empieza por los jobs con mayores privilegios y las acciones de terceros.