Skip to main content

Cómo crear un pipeline de CI/CD seguro con GitHub Actions para tu aplicación Java

Escrito por

27 de junio de 2022

0 minutos de lectura

GitHub Actions facilita más que nunca crear un pipeline seguro de integración continua y entrega continua (CI/CD) para tus proyectos de GitHub. Al integrar tu pipeline de CI/CD con tu repositorio de GitHub, GitHub Actions te permite automatizar la compilación, las pruebas y el despliegue. Puedes crear flujos de trabajo para compilar y probar cada pull request de tu repositorio, o desplegar en producción los pull requests combinados. Además, al integrar Snyk en tu CI/CD de GitHub, puedes automatizar el análisis de seguridad como parte del ciclo de compilación antes de pasar a producción.

Cómo configurar un pipeline de CI con GitHub Actions para Java

Los flujos de trabajo de GitHub Actions son archivos YAML que se encuentran en la carpeta .github/workflows. Si no tienes un flujo de trabajo o quieres agregar uno, selecciona Actions y New workflow.

Página de GitHub Actions que muestra la sección Workflows, un botón New workflow y la opción All workflows seleccionada.

Para este proyecto de Java Spring Boot, creé un pipeline de CI con Maven de la siguiente manera:

name: Java CI with Maven

on:
 push:
   branches: [ master ]
 pull_request:
   branches: [ master ]
 workflow_dispatch:

jobs:
 build:

   runs-on: ubuntu-latest

   steps:
   - uses: actions/checkout@v2
   - name: Set up JDK 17
     uses: actions/setup-java@v1
     with:
       java-version: 17
   - name: Build with Maven
     run: mvn -B package --file pom.xml

Esta acción se ejecutará en cada push o pull request a la rama master. Se basa en Ubuntu y hace checkout del repositorio. Además, usa GitHub Action setup-java —con Java 17 y Maven— para compilar el archivo jar de Java. Si conoces la sintaxis, este flujo de trabajo es relativamente sencillo, pero puedes consultar la documentación de GitHub Actions para obtener una descripción completa de las posibilidades.

Cómo integrar Snyk en tu CI/CD de GitHub

Con Snyk, puedes integrar pruebas de seguridad en tu nuevo proyecto Java. Hay dos métodos principales para hacerlo. Antes, asegurémonos de tener dos cosas configuradas. Primero, inicia sesión en tu cuenta de Snyk o crea una gratis si aún no tienes una. Luego, configura tu clave de API como un secreto SNYK_TOKEN en tu repositorio de GitHub.

Opción 1: integrar la CLI de Snyk en un paso de compilación de tu GitHub Action

Puedes usar la CLI de Snyk para ejecutar automáticamente análisis de seguridad durante tu compilación actual. Sigue los pasos que se describen a continuación —incluidos los pasos adicionales después de Build with Maven— para comenzar.

 - name: Set up Node 14
   uses: actions/setup-node@v3
   with:
     node-version: 14
 - name: install Snyk CLI
   run: npm install -g snyk
 - name: run Snyk Open Source Test
   run: snyk test
 - name: run Snyk Code Test
   run: snyk code test

Configura NodeJS versión 14 y descarga la CLI de Snyk con npm. Luego, analiza tus dependencias con Snyk Open Source y usa Snyk Code para buscar vulnerabilidades en tu código personalizado.

Luego, declara SNYK_TOKEN como la variable de entorno que contiene tu clave de API. Puedes usar el secreto SNYK_TOKEN que configuraste antes o reutilizar el ejemplo de código completo de GitHub Action.

env:
 SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

La ventaja de este enfoque es que solo tienes que compilar y construir tu aplicación una vez, lo que puede ahorrar mucho tiempo al crear aplicaciones grandes. La desventaja es que los pasos se ejecutan en serie y podrían no ser eficientes si falla alguno de los pasos posteriores.

Opción 2: usar las GitHub Actions predefinidas de Snyk para crear tu pipeline de CI/CD

Snyk creó un conjunto de GitHub Actions para detectar vulnerabilidades en tus proyectos. La acción que necesitas depende de tu lenguaje de programación o herramienta de compilación. Por ejemplo, para nuestro proyecto Java usaremos la GitHub Action basada en Maven que se muestra a continuación.

Las acciones predefinidas garantizan que tengas los requisitos previos correctos para compilar tu aplicación e incluyen la versión más reciente de la CLI para analizar tu código. Aunque es posible que vuelvas a compilar tus aplicaciones varias veces, estas acciones pueden ejecutarse por separado y en paralelo, una ventaja considerable de este enfoque.

Comencemos por analizar nuestras dependencias. Ya tenemos una cuenta de Snyk y nuestra clave de API está guardada como un secreto llamado SNYK_TOKEN. Así que, en lugar de crear un paso adicional en el trabajo de compilación, crea un nuevo trabajo llamado opensource-security.

opensource-security:
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@master
     - name: Run Snyk to check for vulnerabilities
       uses: snyk/actions/maven@master
       env:
         SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

Según la documentación, el comando predeterminado es test. Sin ninguna configuración adicional, analizará tu aplicación para detectar vulnerabilidades conocidas en las dependencias. Si quieres establecer un argumento específico de la CLI, como --all-projects, para incluir proyectos anidados, usa la palabra clave with y establece la propiedad en args.

Tabla de propiedades, valores predeterminados y descripciones de Snyk Maven Action para args, command y la salida JSON.

Mientras Snyk analiza nuestras dependencias, revisemos el código Java para detectar vulnerabilidades en nuestra GitHub Action. Para hacerlo, repite el proceso anterior, configura un tercer trabajo específicamente para esto y establece la propiedad command en code test.

 code-security:
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@master
     - name: Run Snyk to check for vulnerabilities
       uses: snyk/actions/maven@master
       env:
         SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
       with:
         command: code test

Ten en cuenta que los tres trabajos se ejecutarán en paralelo, lo que en muchos casos resulta más eficiente.

Cómo agregar entrega continua segura a tu CI/CD de GitHub

Ahora hablemos de la parte de despliegue —o entrega— de tu CI/CD de GitHub. Una vez completadas la compilación y las pruebas, es hora de publicar el paquete en GitHub. Para ello, usaremos el plugin Maven Release en nuestro proyecto Java.

Como solo queremos publicar el paquete cuando el trabajo de compilación y los dos trabajos de seguridad hayan finalizado correctamente, agregaremos una propiedad needs con una lista de los trabajos previos necesarios para la publicación. Así nos aseguramos de que el paquete no se despliegue antes de estar completamente compilado y protegido.

release:
   needs: [opensource-security, code-security, build]
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@v2
     - name: Set up JDK 17
       uses: actions/setup-java@v1
       with:
         java-version: 17
     - name: Set Git user
       run: |
         git config user.email "ghactions@brianvermeer.nl"
         git config user.name "GitHub Actions"
     - name: Publish JAR
       run: mvn -B release:prepare release:perform -DskipTests
       env:
         GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Los comandos de Maven release:prepare y release:perform verifican que la versión del lanzamiento sea la correcta y publican el paquete en nuestro repositorio de GitHub. Como confiamos en que Maven se encargue de esto, realiza las siguientes configuraciones en tu archivo pom.xml.

  <scm>
       <developerConnection>scm:git:https://github.com/bmvermeer/ghaction-example.git</developerConnection>
       <tag>HEAD</tag>
   </scm>
   <distributionManagement>
       <repository>
           <id>github</id>
           <name>GitHub</name>
           <url>https://maven.pkg.github.com/bmvermeer/ghaction-example</url>
       </repository>
   </distributionManagement>

Aunque nuestra aplicación recién publicada no tiene vulnerabilidades en este momento, eso no significa que seguirá siendo segura para siempre. Pueden surgir nuevas vulnerabilidades en distintos lugares, por lo que es fundamental monitorear continuamente tu código y tus dependencias después de desplegar una aplicación.

Además de analizar durante el desarrollo, también podemos usar Snyk para monitorear las dependencias después del despliegue. Cuando finalice la publicación, vuelve a usar la acción predefinida de Snyk, pero esta vez establece la propiedad command en monitor.

 opensource-monitor:
   needs: [release]
   runs-on: ubuntu-latest
   steps:
     - uses: actions/checkout@master
     - name: Run Snyk to check for vulnerabilities
       uses: snyk/actions/maven@master
       env:
         SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
       with:
         command: monitor

Esto enviará a Snyk el árbol de dependencias, que no cambia después de la publicación, para que lo monitoree. Ahora podemos ver nuestro proyecto en la interfaz de Snyk y recibir notificaciones automáticas si se encuentra una nueva vulnerabilidad en alguna de las dependencias que usamos. Así nos aseguramos de que nuestro proyecto Java publicado siga libre de vulnerabilidades.

Panel de proyectos de Snyk que muestra «nl.brianvermeer.snyk:ghaction-example», cero problemas y un enlace para ver el informe

Cómo integrar la seguridad en tus GitHub Actions

Con GitHub Actions, crear un pipeline de CI/CD para tu proyecto de GitHub es muy sencillo. Además, con las acciones de Snyk puedes integrar fácilmente el análisis de seguridad en varios niveles para todas tus aplicaciones.

GitHub muestra el pipeline que creamos hoy en la siguiente imagen. Algunos trabajos se ejecutan en paralelo, mientras que otros dependen de que se completen correctamente otros trabajos. Puedes consultar el proyecto de ejemplo completo en este repositorio de GitHub.

Flujo de trabajo de GitHub Actions que muestra tareas exitosas de compilación, seguridad, lanzamiento y monitoreo de código abierto, activadas al hacer push

Hoy usamos Snyk Code y Snyk Open Source para analizar el código fuente de Java y las dependencias del pipeline. Sin embargo, puedes ampliar el análisis a archivos de Docker con Snyk Container y archivos de Kubernetes con Snyk IaC.

Con Snyk GitHub Actions, puedes agregar análisis automáticamente a tu flujo de trabajo de GitHub Actions y combinar las acciones que mejor se adapten a tu proyecto para proteger el código ahora y en el futuro.

Empieza con los retos de Capture the Flag

Aprende a resolver retos de Capture the Flag viendo nuestro taller virtual de nivel básico a pedido.

Leer más

Blog

Los modelos de frontera encontraron las vulnerabilidades. Solo el atacante encontró las cadenas.

El análisis estático encontró las fallas, pero solo las pruebas de ataque en vivo demostraron cómo podían encadenarse para provocar brechas. Una comparación de Evo COS, Claude Security y Claude Code Security.

feature insights context
Blog

Los ataques autónomos ya están aquí. La defensa debe estar a su altura.

Los atacantes autónomos están reduciendo el tiempo disponible para defenderse. Descubre cómo el descubrimiento, la corrección, la validación y la prevención continuos pueden ayudar a los equipos de seguridad a seguirles el ritmo.

Blog

Por qué los agentes de programación con IA siguen generando fallas de control de acceso

Los agentes de programación con IA pueden generar lógica de autorización que compila y supera la revisión, pero expone los datos de un inquilino a otro. Descubre por qué es difícil detectar el control de acceso roto y cómo prevenirlo.