Buscar vulnerabilidades en tu flujo de GitOps con Azure DevOps

En los artículos anteriores estuve mostrándote algunas ideas de cómo integrar los flujos de integración continua con los repositorios destinados a GitOps, tanto para manifiestos planos como con Helm. Sin embargo, no quería perder la oportunidad de añadir la parte que le toca de la cultura de DevSecOps a este flujo, ya que a día de hoy los manifiestos que vamos a desplegar también son objeto de análisis y podemos detectar potenciales vulnerabilidades en la configuración, que estamos dispuestos a proponer para nuestro entorno productivo. En este artículo te cuento cómo controlarlo con Azure DevOps.

El flujo de GitOps

Siguiendo el flujo anterior con Argo CD, aunque podría ser con cualquier otro operador, la idea es tener algo como lo siguiente:

Validación de los manifiestos durante la pull request
Validación de los manifiestos durante la pull request

Cada vez que alguien intente hacer una pull request con los manifiestos que venimos definiendo en fases anteriores de desarrollo y pruebas haya una validación que verifique si lo que estamos intentando mergear con el branch de producción (o el que sea) está cumpliendo con las buenas prácticas desde el punto de vista de seguridad. Hay diferentes herramientas que se pueden usar en este punto como PSRule, Snyk, Kubescape, entre otros. En este ejemplo lo voy a mostrar con Kubescape.

Pipeline para la validación

En el caso de Azure DevOps, para llevar a cabo esta tarea he creado una pipeline como la siguiente:

trigger: none
pool:
  vmImage: ubuntu-latest
steps:
- script: |
    brew tap armosec/kubescape
    brew install kubescape
  displayName: 'Install kubescape'
- script: helm template tour-of-heroes-helm --dry-run | kubescape scan -
  displayName: 'Scan local Helm before merging'

Como ves, el flujo es súper sencillo: no tiene ningún trigger y simplemente instalo la herramienta y ejecuto la misma según convenga. En el caso de Kubescape esta sería la forma de utilizarla con Helm, pero también puedes usarla del siguiente modo con manifiestos planos:

trigger: none
pool:
  vmImage: ubuntu-latest
steps:
- script: |
    brew tap armosec/kubescape
    brew install kubescape
  displayName: 'Install kubescape'
- script: kubescape scan *.yaml --fail-threshold 40
  displayName: 'Scan local yaml before merging'

Como ves, también podemos usar el parámetro –fail-theshold para indicar el porcentaje de fallos permitidos en la configuración. Aquí puedes encontrar más información sobre esta herramienta en concreto y los diferentes usos.

Te recomiendo que una vez que la generes la ejecutes de forma manual para comprobar sus resultados en el apartado Pipelines.

¿Cómo la ejecuto durante las pull requests?

Una vez que has probado tu pipeline, y has definido qué herramientas quieres utilizar para el análisis, lo que puedes hacer es lo siguiente: puedes proteger el branch de producción, por ejemplo main, seleccionando el mismo en el apartado Repo > Branches y haciendo clic en su menú para seleccionar la opción Branch policies.

Repos - Branches- main - Branch policies
Repos – Branches- main – Branch policies

Dentro de este apartado debes hacer clic sobre el + de Build validation:

Azure DevOps - Add new build policy
Azure DevOps – Add new build policy

Busca entre las pipelines la que acabas de crear para las pull requests (debe de estar dada de alta antes en la sección Pipelines para que aparezca en este combo) y darle un nombre descriptivo a esta validación:

Azure DevOps - Add Build validation - Add build policy
Azure DevOps – Add Build validation – Add build policy

A partir de ahora cada vez que alguien solicite que los manifiestos deben pasar a un siguiente branch se validará previamente si cumplen con las buenas prácticas desde el punto de vista de seguridad:

Ejecutando kubescape durante la Pull Request en Azure DevOps

¡Saludos!