Afhankelijkheden
Wat is een dependency graph?
Een dependency graph brengt elk pakket in kaart waarvan uw software afhankelijk is, en welk pakket het heeft binnengebracht. Een lijst vertelt u wat er in uw software zit. De graph vertelt u waarom het er zit en wat het verder raakt, en dat is precies de vraag die u hebt wanneer een kwetsbaarheid opduikt.
Bijgewerkt op
Nodes, edges en paden
In een dependency graph is elk pakket een node, en elke "is afhankelijk van" een edge van het ene pakket naar het andere. Uw project staat bovenaan. De directe afhankelijkheden liggen één edge verderop, en de transitieve afhankelijkheden zijn alles wat daaronder ligt. De route van uw project naar een pakket is het afhankelijkheidspad van dat pakket, en één pakket kan er meerdere hebben.
Graph, boom of lijst
Dezelfde afhankelijkheden kunnen op drie manieren worden weergegeven, en elke manier beantwoordt een andere vraag.
| Weergave | Wat die toont | Wat die verliest |
|---|---|---|
| Platte lijst | Elk pakket één keer, met zijn versie | Waarom elk pakket er staat |
| Boom | Elk pad vanaf uw project, zoals pakketbeheerders het tonen | Gedeelde pakketten herhalen zich, dus de boom lijkt groter dan hij is |
| Graph | Elk pakket één keer, met een edge vanaf elk bovenliggend pakket | Moeilijker met het blote oog te lezen zonder viewer |
Gedeelde pakketten zijn de reden dat graphs ertoe doen. Wanneer twee van uw afhankelijkheden hetzelfde pakket nodig hebben, vormt dat een ruit: één node met twee bovenliggende pakketten. Om een kwetsbaarheid daarin te repareren, moet u beide paden kennen, want elk van beide bovenliggende pakketten kan de oude versie vastpinnen.
Waarvoor u een dependency graph gebruikt
- Het fixpad vinden. Een kwetsbaar transitief pakket repareert u door iets op zijn pad te upgraden of te overschrijven. De graph toont welke directe afhankelijkheid u moet bijwerken.
- De blast radius meten. Wanneer er een advisory verschijnt, toont de graph welke van uw directe afhankelijkheden, services en producten naar het getroffen pakket leiden.
- Licenties beoordelen. Een copyleftlicentie diep in de graph is even bindend als een licentie bovenaan, en het pad vertelt u welke afhankelijkheid die heeft binnengebracht.
- Upgrades plannen. Een grote upgrade van één pakket verandert alles eronder. De graph toont hoeveel van uw boom meeverandert.
- Risicoconcentratie opsporen. Een klein, niet-onderhouden pakket waar veel paden doorheen lopen, is een single point of failure.
Hoe u een dependency graph krijgt
Van uw pakketbeheerder. Elke pakketbeheerder toont de opgeloste boom, en de meeste kunnen uitleggen waarom een enkel pakket er staat. Transitieve afhankelijkheden vermeldt de opdrachten voor npm, pnpm, Python, Go, Rust, Maven en Gradle.
Van GitHub. De dependency graph onder het tabblad Insights van een repository is een samenvatting van de manifests en lockfiles in de repository, plus afhankelijkheden die via de dependency submission API zijn ingediend. Voor ecosystemen die dat ondersteunen, toont GitHub het transitieve pad dat elke afhankelijkheid heeft binnengebracht, en het kan de graph als SBOM exporteren.
Uit een SBOM. CycloneDX legt de graph vast in een sectie dependencies, waarin elk component vermeldt waarvan het afhankelijk is. SPDX gebruikt DEPENDS_ON-relaties tussen pakketten. Een CycloneDX-graph voor een deel van een Express-app ziet er zo uit:
"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"] }
] Hier verschijnt debug onder twee bovenliggende pakketten: een ruit. Veel SBOM's laten de relaties weg en vermelden alleen componenten, waardoor de inventaris behouden blijft maar elk pad verloren gaat.
Een graph is maar zo goed als zijn bron
De meeste dependency graphs worden opgebouwd uit manifests en lockfiles, dus ze tonen de boom die de pakketbeheerder heeft gepland. Ze tonen geen pakketten die uit CI-caches zijn teruggezet, buildtools die door setupstappen zijn geïnstalleerd of code die door installatiescripts en downloads is opgehaald, en ze kunnen niet vertellen of de build exact de lockfile heeft geïnstalleerd. Zie waarom een lockfile niet vastlegt wat is geleverd.
Dependency graphs in CRACI
CRACI bouwt zijn graph op uit de build zelf. Het is een GitHub Actions-runner die elk pakket vastlegt dat elke job ophaalt, op elk niveau van de boom en inclusief pakketten die uit CI-caches zijn teruggezet, in een SBOM die zijn eigen volledigheid vermeldt.
- Een graphweergave van de SBOM. De dependencies-weergave toont de afhankelijkheidslagen van de SBOM in de weergaven Pivot, Graph, Blob, Chord en Sunburst, met filters voor diepte en ernst.
- Exports met de volledige boom. CycloneDX- en SPDX-exports bevatten transitieve afhankelijkheden, elk met de gedeclareerde licentie.
- Getroffen builds in de loop van de tijd. Wanneer een nieuwe kwetsbaarheid opduikt, toont de buildgeschiedenis welke eerdere builds het kwetsbare pakket bevatten, direct of transitief.
Zie SBOM-generatie in CRACI, of boek een demo om de graph van een van uw eigen builds te verkennen.
Dependency graphs: veelgestelde vragen
Wat is een dependency graph?
Een dependency graph is een kaart van elk pakket waarvan uw software afhankelijk is, met een pijl van elk pakket naar de pakketten die het nodig heeft. Hij toont niet alleen wat er in uw software zit, maar ook waarom: het pad van uw code naar elke transitieve afhankelijkheid.
Wat is het verschil tussen een dependency tree en een dependency graph?
Een boom toont elk pad apart, dus een pakket dat twee bovenliggende pakketten nodig hebben, verschijnt twee keer. Een graph toont elk pakket één keer, met een edge vanaf elk bovenliggend pakket dat het nodig heeft. Pakketbeheerders tonen bomen omdat die makkelijk te lezen zijn; tools die impact analyseren, werken op de graph.
Bevat een SBOM een dependency graph?
Dat kan. CycloneDX heeft een dependencies-sectie waarin elk component de componenten vermeldt waarvan het afhankelijk is, en SPDX drukt hetzelfde uit met DEPENDS_ON-relaties. Veel SBOM's laten de relaties weg en vermelden alleen componenten, waardoor de paden verloren gaan.
Hoe zie ik de dependency graph van een GitHub-repository?
Open het tabblad Insights van de repository en kies Dependency graph. GitHub bouwt de graph op uit de manifests en lockfiles in de repository, plus alles wat via de dependency submission API is ingediend, en toont voor ecosystemen die dat ondersteunen het pad dat elke transitieve afhankelijkheid heeft binnengebracht.
Wat is een diamond dependency?
Twee van uw afhankelijkheden zijn allebei afhankelijk van hetzelfde pakket, waardoor de graph een ruit vormt. Hebben ze incompatibele versies ervan nodig, dan moet de pakketbeheerder twee kopieën installeren of mislukt de installatie, en dat is een van de manieren waarop een graph moeilijker te beheren wordt dan hij eruitziet.
Zie de graph van wat uw build binnenhaalde
Laat één GitHub Actions-workflow op CRACI draaien en verken de dependency graph van de vastgelegde SBOM, op elk niveau van de boom.
Demo boeken