feat(devsecops): agregar Trivy (imagen + IaC) al pipeline del frontend
trivy config sobre frontend.yaml (CRITICAL/HIGH/MEDIUM, informativo) y trivy image sobre la imagen recién construida (CRITICAL bloquea con --ignore-unfixed, HIGH solo informa), entre build (push:false, load:true) y el push real al registry. Fix real encontrado al validar contra la imagen real: el stage runner heredaba npm/npx/corepack completos de la imagen base de Node sin necesitarlos en runtime, trayendo CVE-2026-59873 (CRITICAL, node-tar empaquetado en npm). Sacarlos del stage final baja CRITICAL de 1 a 0 y HIGH fixable de 21 a 15 (las que quedan son de la propia app, ej. next desactualizado, documentadas como pendiente sin bloquear). Documenta ambos scans en docs/devsecops/trivy.md con los hallazgos reales de este repo.
This commit is contained in:
@@ -235,6 +235,31 @@ jobs:
|
||||
|
||||
echo "OK: navegación real del catálogo validada."
|
||||
|
||||
- name: Instalar Trivy
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
TRIVY_VERSION="0.74.0"
|
||||
curl -sSfL \
|
||||
"https://github.com/aquasecurity/trivy/releases/download/v${TRIVY_VERSION}/trivy_${TRIVY_VERSION}_Linux-64bit.tar.gz" \
|
||||
-o /tmp/trivy.tar.gz
|
||||
tar -xzf /tmp/trivy.tar.gz -C /tmp trivy
|
||||
chmod +x /tmp/trivy
|
||||
/tmp/trivy version
|
||||
|
||||
# Escanea el manifiesto Kubernetes real del frontend (no la imagen):
|
||||
# contenedores como root, falta de resource limits, falta de
|
||||
# readiness/liveness probes, etc. Informativo por ahora — no bloquea
|
||||
# el pipeline mientras revisamos juntos qué hallazgos son reales.
|
||||
- name: Escanear manifiestos Kubernetes (Trivy IaC)
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
/tmp/trivy config \
|
||||
--severity CRITICAL,HIGH,MEDIUM \
|
||||
--exit-code 0 \
|
||||
"${MANIFEST_FILE}"
|
||||
|
||||
- name: Login en Gitea Registry
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
@@ -243,14 +268,50 @@ jobs:
|
||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
logout: true
|
||||
|
||||
- name: Construir y Subir Imagen
|
||||
# push: false — la imagen se queda cargada en el daemon local (load:
|
||||
# true) para poder escanearla con Trivy antes de subirla al registry.
|
||||
- name: Construir Imagen
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: workloads/ecommerce/
|
||||
push: true
|
||||
push: false
|
||||
load: true
|
||||
tags: |
|
||||
gitea.cruzcloud.net/devops/ecommerce-frontend:${{ steps.vars.outputs.VERSION }}
|
||||
gitea.cruzcloud.net/devops/ecommerce-frontend:latest
|
||||
${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.VERSION }}
|
||||
${{ env.IMAGE_NAME }}:latest
|
||||
|
||||
# CRITICAL bloquea el pipeline: no se sube una imagen con una CVE
|
||||
# crítica conocida y con fix disponible.
|
||||
- name: Escanear imagen (Trivy) — CRITICAL bloquea
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
/tmp/trivy image \
|
||||
--severity CRITICAL \
|
||||
--exit-code 1 \
|
||||
--ignore-unfixed \
|
||||
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
|
||||
|
||||
# HIGH solo informa por ahora — no bloquea mientras aprendemos a leer
|
||||
# los reportes y decidimos, con calma, qué reglas deben bloquear.
|
||||
- name: Escanear imagen (Trivy) — HIGH informativo
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
/tmp/trivy image \
|
||||
--severity HIGH \
|
||||
--exit-code 0 \
|
||||
--ignore-unfixed \
|
||||
"${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
|
||||
|
||||
# Login ya se hizo arriba; recién acá se sube, después de que la
|
||||
# imagen pasó el gate de CRITICAL.
|
||||
- name: Subir Imagen al Registry
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker push "${IMAGE_NAME}:${{ steps.vars.outputs.VERSION }}"
|
||||
docker push "${IMAGE_NAME}:latest"
|
||||
|
||||
# Evita que una ejecución antigua actualice frontend.yaml después de que
|
||||
# ya exista un commit más reciente en main.
|
||||
|
||||
Reference in New Issue
Block a user