Afhængigheder
Hvad er en afhængighedsgraf?
En afhængighedsgraf kortlægger hver pakke, din software afhænger af, og hvilken pakke der trak den ind. En liste fortæller dig, hvad der er i din software. Grafen fortæller dig, hvorfor det er der, og hvad det ellers berører, og det er det spørgsmål, du står med, når en sårbarhed dukker op.
Opdateret
Noder, kanter og stier
I en afhængighedsgraf er hver pakke en node, og hvert "afhænger af" er en kant fra én pakke til en anden. Dit projekt ligger øverst. Dets direkte afhængigheder er én kant væk, og dets transitive afhængigheder er alt længere nede. Ruten fra dit projekt til en given pakke er dens afhængighedssti, og én pakke kan have flere.
Graf, træ eller liste
De samme afhængigheder kan vises på tre måder, og hver af dem besvarer et andet spørgsmål.
| Visning | Hvad den viser | Hvad den mister |
|---|---|---|
| Flad liste | Hver pakke én gang, med sin version | Hvorfor hver pakke er der |
| Træ | Hver sti fra dit projekt, som pakkehåndteringer udskriver dem | Delte pakker gentages, så træet overdriver størrelsen |
| Graf | Hver pakke én gang, med en kant fra hver forælder | Sværere at læse med det blotte øje uden et visningsværktøj |
Delte pakker er grunden til, at grafer betyder noget. Når to af dine afhængigheder har brug for den samme pakke, danner den en diamant: én node med to forældre. For at rette en sårbarhed i den skal du kende begge stier, fordi begge forældre kan fastlåse den gamle version.
Det bruger du en afhængighedsgraf til
- At finde vejen til rettelsen. En sårbar transitiv pakke rettes ved at opgradere eller tilsidesætte noget på dens sti. Grafen viser, hvilken direkte afhængighed du skal flytte.
- At måle sprængradius. Når en advisory udsendes, viser grafen, hvilke af dine direkte afhængigheder, tjenester og produkter der fører til den berørte pakke.
- At gennemgå licenser. En copyleft-licens dybt i grafen gælder lige så meget som en øverst, og stien fortæller dig, hvilken afhængighed der bragte den ind.
- At planlægge opgraderinger. En større opgradering af én pakke ændrer alt under den. Grafen viser, hvor meget af dit træ der flytter sig.
- At spotte koncentration af risiko. En lille, uvedligeholdt pakke, som mange stier går igennem, er et enkelt fejlpunkt.
Sådan får du en afhængighedsgraf
Fra din pakkehåndtering. Alle pakkehåndteringer udskriver det resolvede træ, og de fleste kan forklare, hvorfor en enkelt pakke er der. Transitive afhængigheder angiver kommandoerne til npm, pnpm, Python, Go, Rust, Maven og Gradle.
Fra GitHub. Afhængighedsgrafen under et repositorys Insights-fane er en opsummering af manifesterne og lockfilerne i repositoriet plus afhængigheder indsendt via dependency submission API'et. For økosystemer, der understøtter det, viser GitHub den transitive sti, der trak hver afhængighed ind, og det kan eksportere grafen som en SBOM.
Fra en SBOM. CycloneDX registrerer grafen i en dependencies-sektion, hvor hver komponent angiver, hvad den afhænger af. SPDX bruger DEPENDS_ON-relationer mellem pakker. En CycloneDX-graf for en del af en Express-app ser sådan ud:
"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"] }
] Her optræder debug under to forældre: en diamant. Mange SBOM'er udelader relationerne og angiver kun komponenter, så fortegnelsen bevares, men alle stierne går tabt.
En graf er kun så god som sin kilde
De fleste afhængighedsgrafer bygges ud fra manifester og lockfiles, så de viser det træ, pakkehåndteringen planlagde. De viser ikke pakker gendannet fra CI-caches, build-værktøjer installeret af setup-trin eller kode hentet af install-scripts og downloads, og de kan ikke afgøre, om buildet installerede præcis det, der står i lockfilen. Se hvorfor en lockfile ikke er en registrering af det leverede.
Afhængighedsgrafer i CRACI
CRACI bygger sin graf ud fra selve buildet. Det er en GitHub Actions-runner, der registrerer hver pakke, hvert job henter, i alle lag af træet og inklusive pakker gendannet fra CI-caches, i en SBOM, der angiver sin egen fuldstændighed.
- En grafvisning af SBOM'en. Afhængighedsvisningen viser SBOM'ens afhængighedslag i visningerne Pivot, Graph, Blob, Chord og Sunburst, med filtre for dybde og alvorlighed.
- Eksporter med hele træet. Eksporter i CycloneDX og SPDX indeholder transitive afhængigheder, hver med sin deklarerede licens.
- Berørte builds over tid. Når en ny sårbarhed dukker op, viser build-historikken, hvilke tidligere builds der indeholdt den sårbare pakke, direkte eller transitiv.
Se SBOM-generering i CRACI, eller book en demo for at udforske grafen for et af dine egne builds.
Afhængighedsgrafer: ofte stillede spørgsmål
Hvad er en afhængighedsgraf?
En afhængighedsgraf er et kort over hver pakke, din software afhænger af, med en pil fra hver pakke til de pakker, den har brug for. Den viser ikke kun, hvad der er i din software, men også hvorfor: stien fra din kode til hver transitiv afhængighed.
Hvad er forskellen på et afhængighedstræ og en afhængighedsgraf?
Et træ viser hver sti for sig, så en pakke, som to forældre har brug for, optræder to gange. En graf viser hver pakke én gang, med en kant fra hver forælder, der har brug for den. Pakkehåndteringer udskriver træer, fordi de er lette at læse; værktøjer, der analyserer konsekvenser, arbejder på grafen.
Indeholder en SBOM en afhængighedsgraf?
Det kan den. CycloneDX har en dependencies-sektion, hvor hver komponent angiver de komponenter, den afhænger af, og SPDX udtrykker det samme med DEPENDS_ON-relationer. Mange SBOM'er udelader relationerne og angiver kun komponenter, og så går stierne tabt.
Hvordan ser jeg afhængighedsgrafen for et GitHub-repository?
Åbn repositoriets Insights-fane, og vælg Dependency graph. GitHub bygger den ud fra manifesterne og lockfilerne i repositoriet plus alt, der er indsendt via dets dependency submission API, og for økosystemer, der understøtter det, viser den stien, der trak hver transitiv afhængighed ind.
Hvad er en diamantafhængighed?
To af dine afhængigheder afhænger begge af den samme pakke, så grafen danner en diamant. Har de brug for inkompatible versioner af den, må pakkehåndteringen installere to kopier eller fejle, og det er en af måderne, en graf bliver sværere at styre, end den ser ud til.
Se grafen over det, dit build trak ind
Kør ét GitHub Actions-workflow på CRACI, og udforsk afhængighedsgrafen for dets registrerede SBOM, i alle lag af træet.
Book en demo