# SBOM (Syft) — inventario de software !!! info "Qué es un SBOM" SBOM = *Software Bill of Materials* — literalmente, una "lista de materiales" del software, igual que la lista de ingredientes de un producto. Es un documento (JSON, en este caso) que enumera **cada paquete que terminó dentro de la imagen final**: nombre, versión exacta, de dónde viene (`npm`, `deb`, etc.) y, cuando aplica, su licencia. [Syft](https://github.com/anchore/syft) genera ese inventario inspeccionando la imagen Docker ya construida — no necesita acceso al código fuente ni a `package.json`, lee directamente lo que quedó instalado en los layers de la imagen. ## Por qué importa: el escenario "log4shell" En diciembre de 2021 apareció una vulnerabilidad crítica en Log4j (una librería de logging de Java) usada, directa o indirectamente, en una cantidad enorme de software. La pregunta que todo equipo tuvo que responder en horas, no en días, fue: **"¿nosotros usamos esto, en algún lugar, aunque sea una dependencia de una dependencia?"** Sin un SBOM, esa respuesta implica revisar manualmente cada `package.json`, cada imagen Docker, cada servicio — y confiar en que no se te escapó una dependencia transitiva de tres niveles de profundidad. Con un SBOM generado en cada build y guardado como artifact, la respuesta es una búsqueda de texto sobre un archivo: ```bash grep -i "nombre-del-paquete-afectado" sbom.cdx.json ``` Si aparece, sabés exactamente en qué versión, y podés cruzarlo contra el aviso de seguridad para saber si tu versión específica está afectada — en minutos, no en una auditoría manual del repo completo. ## Qué genera este pipeline Un step de Syft corre sobre la imagen ya construida (la misma que pasó el gate de CRITICAL de Trivy) y produce **dos formatos** del mismo inventario, publicados como artifact del pipeline: - `sbom.cdx.json` — [CycloneDX](https://cyclonedx.org/), el formato con mejor soporte en herramientas de consulta/alertas automáticas de CVEs. - `sbom.spdx.json` — [SPDX](https://spdx.dev/), el estándar ISO, más orientado a cumplimiento de licencias y trazabilidad legal. No hay una razón fuerte para elegir solo uno en esta etapa — generar ambos cuesta segundos y cada formato es mejor para un caso de uso distinto, así que se publican los dos. ## Resultado real de este build Corriendo Syft contra la imagen real de `workloads/ecommerce`: | Formato | Paquetes listados | |---|---| | CycloneDX | 3528 componentes | | SPDX | 228 paquetes | !!! tip "¿Por qué el número es tan distinto entre formatos?" No es un error — cada formato tiene un nivel de detalle distinto. CycloneDX de Syft incluye entradas más granulares (variantes, sub-paquetes, entradas sin versión resuelta marcadas `UNKNOWN`) mientras que SPDX agrupa a un nivel más alto. Para "¿tengo este paquete, sí o no?" cualquiera de los dos sirve; para conteos exactos, hay que saber cuál se está mirando. Ejemplo de una entrada real (`sbom.cdx.json`, recortado): ```json { "name": "next", "version": "15.5.10", "licenses": [{ "license": { "id": "MIT" } }], "purl": "pkg:npm/next@15.5.10", "properties": [ { "name": "syft:package:language", "value": "javascript" }, { "name": "syft:package:type", "value": "npm" } ] } ``` El campo `purl` (*Package URL*) es el identificador estándar que usan Trivy, Syft, GitHub Advisories y la mayoría de las bases de datos de CVEs para referirse a "este paquete, en este ecosistema, en esta versión" — es lo que hace posible cruzar un SBOM contra un aviso de seguridad de forma automática, sin depender de que el nombre coincida exactamente en texto libre. !!! example "El SBOM también sirve para encontrar cosas que sobran" Revisando el inventario real apareció `yarn@1.22.22` — viene empaquetado en la imagen base de Node igual que el `npm` que ya se sacó del stage final en el fix de [Trivy](trivy.md). No es una vulnerabilidad activa hoy, pero es exactamente el tipo de hallazgo que un SBOM hace visible para revisar después: herramientas que viajan en la imagen de producción sin que el runtime las necesite. ## Cómo se consulta El SBOM se publica como artifact del pipeline (`sbom-v1.0.X`, con ambos archivos) en cada build. Para consultarlo: 1. Descargar el artifact de la corrida del pipeline que te interesa (o del último build de `main`, para saber qué corre en producción ahora mismo). 2. Buscar el paquete en cuestión: ```bash python3 -c " import json d = json.load(open('sbom.cdx.json')) for c in d['components']: if c['name'] == 'next': print(c['name'], c['version']) " ``` (o `grep -A3 '"name": "next"' sbom.cdx.json` si no hay Python a mano). 3. Si el paquete aparece, confirmar la versión contra el aviso de seguridad para saber si aplica. No hace falta memorizar el formato — el punto de tener el SBOM ya generado es no depender de reconstruir esta información bajo presión el día que aparezca la próxima CVE grande.