SBOM
Una SBOM debe describir el build que se distribuyó
Una SBOM durante el build se registra mientras se ejecuta el build, a partir del tráfico que realmente entró en él. La mayoría de los generadores de SBOM reconstruyen en cambio la lista después, a partir del lockfile o de la salida, y así se les escapan las dependencias ocultas que un build descarga por su cuenta. Este es el motivo, y esto es lo que cambia al registrar el build.
Actualizado el
SBOM de build, SBOM de código fuente, SBOM analizada
La guía de CISA sobre tipos de SBOM las clasifica según cuándo y cómo se crean. Tres de esos tipos cubren casi todos los generadores de SBOM en uso:
| Tipo | Cómo se crea | Qué se le puede escapar |
|---|---|---|
| Código fuente | A partir de archivos fuente, manifiestos y lockfiles, normalmente con una herramienta de SCA | Componentes de tiempo de ejecución, plugins o plataforma; todo lo que no esté declarado en los archivos |
| Build | Como parte del build que crea el artefacto publicable | Lo que el entorno de build no pueda ver, y por eso debe indicarse la completitud |
| Analizada | Después del build, analizando un ejecutable, un paquete o una imagen de contenedor | Componentes que la herramienta no reconoce; los resultados dependen de heurísticas |
CISA enumera dos ventajas de una SBOM de build: más confianza en que la SBOM representa correctamente el artefacto, por la
información disponible durante el build y el proceso de CI/CD, y más fiabilidad, porque el mismo workflow de build puede
firmar tanto la SBOM como el artefacto. El inconveniente que menciona es que puede ser necesario cambiar el proceso de
build para generarla. Con CRACI, ese cambio es una línea, runs-on: craci, y el registro viene con el runner.
Escanear una carpeta frente a registrar un build
La mayoría de los generadores de SBOM son escáneres. Se les indica un árbol de código fuente o una imagen de contenedor, y deducen lo que creen que entró leyendo manifiestos, lockfiles, paquetes instalados o binarios. Eso es útil y, para el software que usted no ha compilado, suele ser la única opción.
El punto débil es que un escáner solo ve lo que tiene delante. Si no se añadió ningún lockfile al repositorio, si las dependencias no se instalaron antes del escaneo o si el producto se distribuye como binario compilado, el escáner tiene menos con lo que trabajar que el build. Un escaneo que no encuentra ningún componente produce aun así un documento SBOM válido, y ahí es donde muchos caen.
CRACI adopta otro enfoque. Genera la SBOM dentro de su propio runner de CI, de modo que el artefacto distribuido es el artefacto descrito. No es un escaneo ejecutado en algún lugar cercano.
SBOM basics: SPDX, CycloneDX and OpenVEX
Qué registra una SBOM, en qué se diferencian en la práctica los formatos SPDX y CycloneDX y qué aporta OpenVEX sobre si una vulnerabilidad afecta realmente a un producto.
Petteri Pulkkinen y Erika Marttinen en Kubernetes Community Days Helsinki 2026, 16:50 a 22:05 de SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
De qué depende un escaneo
Syft, Trivy, cdxgen, la Microsoft SBOM Tool, la exportación del grafo de dependencias de GitHub y la CLI de Socket deducen una SBOM a partir de lo que pueden leer. Los patrones siguientes se derivan de cómo funcionan estas herramientas según su documentación.
Las herramientas no se ponen de acuerdo en qué es un componente
Cada generador decide por sí mismo qué cuenta como componente y de qué archivos se fía, de modo que el mismo commit fijado da a cada uno una lista distinta.
Parte de ello es cuestión de nombres. Las herramientas identifican la misma GitHub Action con distintos tipos de package URL, de modo que pueden enumerar lo mismo y aun así no coincidir. Eso también forma parte del problema: una SBOM que utiliza otro identificador para un componente es más difícil de cotejar con los datos de vulnerabilidades.
Haber instalado antes puede importar más que la herramienta
Express 5.2.1 no incluye ningún lockfile en el repositorio. Apuntado a un checkout limpio, un generador que resuelve
dependencias a partir de lockfiles o de un árbol instalado no tiene ni lo uno ni lo otro, de modo que ninguna de las
dependencias npm declaradas en package.json llega al documento. Aun así, puede devolver una lista formada por
lo demás que reconozca, como las GitHub Actions y los archivos de workflow que hacen referencia a ellas. Ninguna de estas
herramientas está rota.
En una copia instalada del mismo repositorio, un flag de Syft vuelve a cambiar la respuesta. La misma herramienta, el mismo árbol, la misma versión. Por diseño, un escaneo de directorio de Syft indica lo que declara un proyecto, y el catalogador que lee los paquetes instalados no está en su conjunto predeterminado para directorios.
Parte del software no tiene ningún manifiesto que leer
El repositorio anthropics/claude-code en la versión v2.1.259 no tiene ningún manifiesto de dependencias: ni
package.json, ni lockfile, ni nada equivalente. Lo que devuelve cada generador se compone a partir de otros
tipos de archivo, de modo que la respuesta dice más de la herramienta que del proyecto.
El paquete npm publicado no es muy distinto. @anthropic-ai/claude-code declara cero dependencias de tiempo de ejecución y ocho paquetes específicos de
plataforma que envuelven un binario precompilado. @openai/codex 0.149.1 tiene la misma forma. Lo que se
ejecuta en la máquina del desarrollador es un binario compilado cuyo interior ningún lector de manifiestos puede ver. No es un
defecto de ninguna herramienta concreta. Es un modelo de distribución que el escaneo a posteriori no puede describir.
Versiones y proveedores
Cuando dos herramientas encuentran el mismo paquete, no siempre coinciden en su versión. Una puede fijar una GitHub Action a un SHA de commit mientras otra indica una etiqueta de versión. Una búsqueda de vulnerabilidades basada en la versión equivocada da una respuesta errónea que parece fiable.
El campo de proveedor, uno de los elementos mínimos de la NTIA, suele quedar vacío, porque la mayoría de los generadores no tienen ninguna fuente para él.
Dependencias ocultas: lo que ningún escaneo puede ver
Todas las herramientas anteriores parten del lockfile o de la salida del build y deducen qué entró. Un build descarga más que eso. Estas dependencias ocultas no figuran en ningún lockfile, de modo que un escaneo no puede encontrarlas:
-
Hooks de instalación. Los scripts
preinstallypostinstallde npm se ejecutan durante la instalación y pueden descargar más código. Así actuó el gusano Shai-Hulud. - Scripts de build. Los scripts de build de Rust, entre otros, descargan lo que necesitan durante el build.
- Imágenes base. Un build de contenedor descarga una imagen base y sus capas del sistema operativo, que ningún lockfile de lenguaje enumera.
- Cachés y herramientas de build. Los paquetes restaurados desde cachés de CI y las herramientas instaladas en pasos de configuración también llegan fuera del lockfile.
Escanear la salida después no cierra la brecha. Un binario terminado, sobre todo el código compilado como Rust, deja al escáner adivinando qué entró en él.
Dos builds, dos SBOM
Hay un segundo motivo por el que un escaneo no puede sustituir al build: la mayoría de los builds no son reproducibles. Compile el mismo commit dos veces seguidas y nada garantiza que obtenga los mismos paquetes. Los gestores de paquetes resuelven e instalan en el orden en que llegan las respuestas, lo que importa sobre todo cuando no hay lockfile, como en muchos proyectos de Python, y los pasos de build pueden incluir su propia aleatoriedad. Los builds reproducibles byte a byte son posibles, con herramientas como Nix, pero son poco frecuentes.
Así, una SBOM generada más tarde, en otra máquina o a partir de otro build, describe un build que quizá nunca se distribuyó. Solo la SBOM registrada durante el build de CI que produjo una versión demuestra lo que hay en producción.
Qué cambia al registrar el build
CRACI ve el tráfico; los escáneres no. Ejecuta sus jobs de GitHub Actions en sus propios runners y ve el tráfico de red que entra en cada build, de modo que la SBOM enumera lo que el job descargó realmente, incluidas las dependencias transitivas y ocultas, y no lo que un manifiesto dice que debería necesitar.
Las cachés son el punto donde el registro durante el build se complica. Un paquete restaurado desde una caché nunca pasa por un registro de paquetes, así que un proxy por sí solo no lo vería. CRACI transporta la evidencia de dependencias junto con la caché, de modo que los paquetes restaurados desde una caché siguen en la SBOM del job que los restauró. Consulte lo que oculta la caché de GitHub Actions.
Los ecosistemas detectados incluyen fuentes npm, PyPI, RubyGems, Cargo, Go, Nix, OCI, apt, apk y Git, además de los presets de descarga de Yocto y OpenEmbedded. Funcionan los mirrors npm y PyPI de JFrog Artifactory. La exportación incluye los metadatos de licencia declarada. Las SBOM se exportan en CycloneDX y SPDX. La página de generación de SBOM cubre la funcionalidad completa.
Ver el tráfico también funciona en la otra dirección. Un build necesita paquetes de fuentes conocidas y publica su salida en lugares conocidos. La política de salida de CRACI solo permite esos destinos y bloquea de inmediato cualquier otra conexión saliente, de modo que el malware que intente enviar sus secretos al servidor de un atacante fracasa. Como la política permite lo que necesita el build en lugar de buscar hosts maliciosos conocidos, se mantiene incluso si usted es el primer objetivo de un ataque que nadie ha visto antes, como ocurrió con Shai-Hulud. Consulte cómo detiene la exfiltración una política de salida.
SBOM de contenedores y Docker
Las imágenes de contenedor son donde más se nota la diferencia. Las formas habituales de obtener una SBOM de Docker analizan
la imagen: Syft y Trivy la escanean, docker scout sbom indexa su contenido cuando la imagen no lleva ninguna
atestación de SBOM, y la atestación de SBOM de BuildKit, activada con --sbom=true, ejecuta por defecto un
escáner basado en Syft sobre la etapa final de la imagen. El antiguo plugin docker sbom está obsoleto en favor
de docker scout sbom.
Cada uno de ellos lee la imagen terminada, de modo que ve lo que todavía es reconocible en las capas. No ve lo que el build descargó por el camino. CRACI registra el job que compila la imagen: las imágenes y los paquetes que el job descarga de registros OCI y fuentes de paquetes entran en la misma SBOM que el resto del build. Para una imagen que usted no haya compilado, escanearla sigue siendo la opción práctica. Consulte qué se les escapa a las SBOM de imágenes Docker.
Completitud, indicada por job
Una SBOM registrada solo es tan buena como el registro. En lugar de presentar todas las SBOM como completas, CRACI indica la completitud de cada job y de cada caché, en uno de cinco estados:
- Complete. CRACI observó evidencia completa del job, y todas las cachés restauradas estaban completas.
- Complete with connections. Se cumplieron los requisitos, pero el job utilizó una o más conexiones de red personalizadas, así que conviene revisar lo que entró por ellas.
- Incomplete. CRACI identificó una circunstancia que podría dejar dependencias fuera de la SBOM.
- Unavailable. CRACI no pudo terminar de evaluar la evidencia.
- Not recorded. El job es anterior a la indicación de completitud.
La completitud es transitiva entre cachés. Si un job restaura una caché incompleta, su SBOM también es incompleta, y cualquier caché que produzca ese job arrastra el estado incompleto. Usted sabe en qué SBOM puede confiar y cuáles necesitan una segunda revisión.
The hard parts: hooks, noise and staying current
Tres problemas que señala la charla: los hooks post-install que descargan cosas que ningún manifiesto enumera, encontrar las dependencias que importan en una lista larga y mantener la SBOM al día, lo que implica generarla en el CI en cada build.
Petteri Pulkkinen y Erika Marttinen en Kubernetes Community Days Helsinki 2026, 25:39 a 27:22 de SBOMbastic: Getting Ready for Upcoming EU Cybersecurity Regulation in Software Supply Chains.
Procedencia a través de la API
La SBOM es una parte de lo que CRACI registra para cada job. La API devuelve SBOM, trazas de red y procedencia, todo registrado a partir del mismo build.
Cuándo un escáner sigue siendo la herramienta adecuada
El registro durante el build cubre el software que usted compila. Para una imagen o un binario de terceros que no haya compilado, un escáner sigue siendo la opción práctica, y las herramientas anteriores son capaces y muy utilizadas. La cuestión no es que los escáneres sean malos. Es que la SBOM de sus propias versiones debe proceder del build que las creó.
Una SBOM de CRACI también tiene sus propios límites. Cubre los jobs que se ejecutan en runners de CRACI, lo que hoy significa GitHub Actions en Linux, con otros sistemas de CI en la hoja de ruta.
¿Está eligiendo entre herramientas? Consulte la comparativa de herramientas de SBOM, o vea cómo encajan las SBOM durante el build en el trabajo de cumplimiento del CRA. Para ver Syft, Trivy y cdxgen frente a frente, consulte lo que se les escapa a los generadores de SBOM de código abierto.
SBOM durante el build: preguntas frecuentes
¿Qué es una SBOM durante el build?
Una SBOM durante el build, que CISA denomina build SBOM, se genera como parte de la compilación del artefacto publicable. En lugar de reconstruir la lista de componentes a partir de archivos después, describe lo que utilizó el propio build. CRACI la registra a partir de los paquetes que cada job de GitHub Actions descargó realmente.
¿Cuál es la diferencia entre una SBOM de build y una SBOM analizada?
Una SBOM analizada se genera después del build analizando un artefacto como un ejecutable o una imagen de contenedor, lo que generalmente requiere heurísticas. Una SBOM de build se genera durante el build, a partir de la información que tiene el build. Las SBOM analizadas funcionan sin acceso al build, lo que las convierte en la opción adecuada para el software que usted no ha compilado.
¿Cómo genero una SBOM para una imagen Docker?
Para una imagen existente, escanéela con un generador como Syft, Trivy o docker scout sbom. BuildKit también puede adjuntar una atestación de SBOM durante el build, escaneando la imagen final. Para registrar lo que incorporó el build de una imagen, ejecútelo en un runner de CRACI: la SBOM del job cubre las imágenes y los paquetes que descargó.
¿Qué son las dependencias ocultas?
Todo lo que un build descarga y que ningún lockfile enumera: el código descargado por los hooks de instalación de npm, los archivos que los scripts de build de Rust descargan durante el build, y la imagen base y sus capas del sistema operativo en un build de contenedor. A las herramientas que leen el lockfile o escanean la salida se les escapan. CRACI las registra porque ve el tráfico que entra en el build.
¿Por qué dos builds del mismo código dan SBOM distintas?
Porque la mayoría de los builds no son reproducibles. El gestor de paquetes resuelve e instala los paquetes en el orden en que llegan las respuestas, sobre todo sin lockfile, y los pasos de build pueden incluir aleatoriedad. Compile el mismo commit dos veces seguidas y el segundo build puede contener paquetes distintos. Solo la SBOM registrada durante el build que produjo una versión demuestra lo que contiene esa versión.
¿Una SBOM durante el build siempre está completa?
No automáticamente. Un registro solo es tan bueno como lo que puede observar, de modo que CRACI indica la completitud de cada job y de cada caché: Complete, Complete with connections, Incomplete, Unavailable o Not recorded. Usted sabe en qué SBOM puede confiar y cuáles necesitan una segunda revisión.
¿Una SBOM durante el build sustituye a los escáneres de SBOM?
Para el software que usted compila, sí: la SBOM de sus versiones debe proceder de los builds que las crearon. Para las imágenes y binarios de terceros que no haya compilado, un escáner sigue siendo la opción práctica. La comparativa de herramientas de SBOM cubre las opciones.
¿Qué generador de SBOM utiliza CRACI?
Ninguno. CRACI no escanea archivos. Un proxy que entiende de paquetes en sus runners registra los paquetes que cada job descarga de fuentes npm, PyPI, RubyGems, Cargo, Go, Nix, OCI, apt, apk y Git, además de los presets de descarga de Yocto y OpenEmbedded, y exporta el resultado en CycloneDX o SPDX.
Compare una SBOM de su propio build
Reserve una demo y ejecute uno de sus workflows en CRACI. Ponga su SBOM junto a la que produce su herramienta actual y vea en qué difieren.
Reservar una demo