Dependencias
¿Qué es un grafo de dependencias?
Un grafo de dependencias representa todos los paquetes de los que depende su software y qué paquete incorporó a cada uno. Una lista le dice qué hay en su software. El grafo le dice por qué está ahí y a qué más afecta, que es la pregunta que surge cuando aparece una vulnerabilidad.
Actualizado el
Nodos, aristas y rutas
En un grafo de dependencias, cada paquete es un nodo y cada relación de dependencia es una arista de un paquete a otro. Su proyecto está en lo más alto. Sus dependencias directas están a una arista de distancia, y sus dependencias transitivas son todo lo que hay más abajo. El camino desde su proyecto hasta cualquier paquete es su ruta de dependencia, y un paquete puede tener varias.
Grafo, árbol o lista
Las mismas dependencias se pueden mostrar de tres formas, y cada una responde a una pregunta distinta.
| Vista | Qué muestra | Qué pierde |
|---|---|---|
| Lista plana | Cada paquete una vez, con su versión | Por qué está ahí cada paquete |
| Árbol | Cada ruta desde su proyecto, tal como la imprimen los gestores de paquetes | Los paquetes compartidos se repiten, de modo que el árbol exagera el tamaño |
| Grafo | Cada paquete una vez, con una arista desde cada padre | Más difícil de leer a simple vista sin un visor |
Los paquetes compartidos son la razón por la que importan los grafos. Cuando dos de sus dependencias necesitan el mismo paquete, se forma un diamante: un nodo con dos padres. Corregir una vulnerabilidad en él exige conocer ambas rutas, porque cualquiera de los dos padres puede fijar la versión antigua.
Para qué se utiliza un grafo de dependencias
- Encontrar la ruta de corrección. Un paquete transitivo vulnerable se corrige actualizando o forzando algo en su ruta. El grafo muestra qué dependencia directa hay que cambiar.
- Medir el radio de impacto. Cuando llega un aviso, el grafo muestra cuáles de sus dependencias directas, servicios y productos conducen al paquete afectado.
- Revisar licencias. Una licencia copyleft en lo más profundo del grafo obliga tanto como una en lo más alto, y la ruta le indica qué dependencia la introdujo.
- Planificar actualizaciones. Una actualización mayor de un paquete cambia todo lo que hay debajo. El grafo muestra qué parte de su árbol cambia.
- Detectar la concentración del riesgo. Un paquete pequeño y sin mantenimiento por el que pasan muchas rutas es un punto único de fallo.
Cómo obtener un grafo de dependencias
Desde su gestor de paquetes. Todos los gestores de paquetes imprimen el árbol resuelto, y la mayoría pueden explicar por qué está ahí un paquete concreto. Dependencias transitivas enumera los comandos para npm, pnpm, Python, Go, Rust, Maven y Gradle.
Desde GitHub. El grafo de dependencias de la pestaña Insights de un repositorio es un resumen de los manifiestos y lockfiles del repositorio, además de las dependencias enviadas mediante la API de envío de dependencias. En los ecosistemas compatibles, GitHub muestra la ruta transitiva que incorporó cada dependencia, y puede exportar el grafo como SBOM.
Desde una SBOM. CycloneDX registra el grafo en una sección dependencies, donde cada componente enumera aquello de lo que depende. SPDX utiliza relaciones DEPENDS_ON entre paquetes. Un grafo de CycloneDX para parte de una aplicación Express tiene este aspecto:
"dependencies": [
{ "ref": "my-app", "dependsOn": ["express"] },
{ "ref": "express", "dependsOn": ["body-parser", "send"] },
{ "ref": "body-parser", "dependsOn": ["raw-body", "debug"] },
{ "ref": "send", "dependsOn": ["mime-types", "debug"] }
] Aquí, debug aparece bajo dos padres: un diamante. Muchas SBOM omiten las relaciones y solo enumeran componentes, lo que conserva el inventario pero pierde todas las rutas.
Un grafo solo es tan bueno como su fuente
La mayoría de los grafos de dependencias se construyen a partir de manifiestos y lockfiles, de modo que muestran el árbol que planificó el gestor de paquetes. No muestran los paquetes restaurados desde cachés de CI, las herramientas de build instaladas en pasos de configuración ni el código que traen los scripts de instalación y las descargas, y no pueden saber si el build instaló exactamente el lockfile. Consulte por qué un lockfile no es un registro de lo distribuido.
Grafos de dependencias en CRACI
CRACI construye su grafo a partir del propio build. Es un runner de GitHub Actions que registra cada paquete que descarga cada job, a cualquier profundidad del árbol e incluidos los paquetes restaurados desde cachés de CI, en una SBOM que indica su propia completitud.
- Una vista de grafo de la SBOM. La vista de dependencias muestra las capas de dependencias de la SBOM en las vistas Pivot, Graph, Blob, Chord y Sunburst, con filtros de profundidad y gravedad.
- Exportaciones con el árbol completo. Las exportaciones en CycloneDX y SPDX incluyen las dependencias transitivas, cada una con su licencia declarada.
- Builds afectados a lo largo del tiempo. Cuando aparece una nueva vulnerabilidad, el historial de builds muestra qué builds anteriores contenían el paquete vulnerable, directo o transitivo.
Consulte la generación de SBOM en CRACI o reserve una demo para explorar el grafo de uno de sus propios builds.
Grafos de dependencias: preguntas frecuentes
¿Qué es un grafo de dependencias?
Un grafo de dependencias es un mapa de todos los paquetes de los que depende su software, con una flecha desde cada paquete hacia los paquetes que necesita. No solo muestra qué hay en su software, sino por qué: la ruta desde su código hasta cada dependencia transitiva.
¿Cuál es la diferencia entre un árbol de dependencias y un grafo de dependencias?
Un árbol muestra cada ruta por separado, de modo que un paquete que necesitan dos padres aparece dos veces. Un grafo muestra cada paquete una sola vez, con una arista desde cada padre que lo necesita. Los gestores de paquetes imprimen árboles porque son fáciles de leer; las herramientas que analizan el impacto trabajan sobre el grafo.
¿Una SBOM contiene un grafo de dependencias?
Puede contenerlo. CycloneDX tiene una sección de dependencias en la que cada componente enumera los componentes de los que depende, y SPDX expresa lo mismo con relaciones DEPENDS_ON. Muchas SBOM omiten las relaciones y solo enumeran componentes, con lo que se pierden las rutas.
¿Cómo veo el grafo de dependencias de un repositorio de GitHub?
Abra la pestaña Insights del repositorio y elija Dependency graph. GitHub lo construye a partir de los manifiestos y lockfiles del repositorio, además de lo que se envíe mediante su API de envío de dependencias, y en los ecosistemas compatibles muestra la ruta que incorporó cada dependencia transitiva.
¿Qué es una dependencia en diamante?
Dos de sus dependencias dependen del mismo paquete, de modo que el grafo forma un diamante. Si necesitan versiones incompatibles de él, el gestor de paquetes tiene que instalar dos copias o fallar, que es una de las razones por las que un grafo resulta más difícil de gestionar de lo que parece.
Vea el grafo de lo que incorporó su build
Ejecute un workflow de GitHub Actions en CRACI y explore el grafo de dependencias de su SBOM registrada, a cualquier profundidad del árbol.
Reservar una demo