
Een praktische gids voor het genereren van CycloneDX-SBOM's met cdxgen voor Node, Python, Java, Go, C/C++ en containers – en wat er verder gaat dan het genereren van de eerste SBOM.
Opmerking: Deze gids is medio juli 2026 gecontroleerd tegen de op dat moment actuele cdxgen-releases. cdxgen wordt actief doorontwikkeld; latere releases kunnen functies toevoegen, bugs verhelpen of het gedrag wijzigen. Raadpleeg de officiële cdxgen-documentatie voor de huidige flags en commando's voordat u op een van de onderstaande voorbeelden vertrouwt.
OWASP cdxgen is de snelste manier om een codebase om te zetten in een CycloneDX-SBOM. Het is de officiële generator in het CycloneDX-ecosysteem.
cdxgen dekt de meeste moderne talen en produceert met één commando een geldige SBOM. Als uw doel vandaag „geef mij een SBOM" is, is dit de tool waarop u kunt vertrouwen.
Deze gids helpt u uw eerste SBOM te krijgen, optionele details erin op te nemen en het genereren van SBOM's in pipelines te operationaliseren. Vervolgens trekt hij een grens die de meeste SBOM-content overslaat. Het bestand genereren is één stap. Het daarna gebruiken is een andere. Weten waar de een eindigt en de ander begint, bespaart u later een verkeerde aanname.
cdxgen installeren
Drie manieren om cdxgen te installeren:
Eén vereiste laat mensen struikelen. C, C++ en Python hebben Java 21 of nieuwer op de machine nodig. cdxgen loopt vast op Java 8 of 11. Installeer een actuele JDK en stel eerst JAVA_HOME in, anders blijft de run zonder duidelijke reden hangen.
Eerste SBOM genereren
Ga naar de projectmap en voer één commando uit.
Dat produceert een CycloneDX-bestand, bom.json. cdxgen detecteert automatisch het projecttype en heeft het meestal bij het rechte eind. Als het ernaast zit, is de uitvoer dun of onjuist. Benoem het type vanaf dag één expliciet met -t.
Voor een repository met meerdere services scant u recursief. cdxgen stelt er één geaggregeerde BOM van samen.
Stel de specificatieversie bewust in. De versie die u uitgeeft, is de versie waaraan klanten en toezichthouders u houden.
Dekking van ecosystemen
cdxgen wint op breedte. Eén tool vervangt een lade vol taalspecifieke plug-ins. De gangbare aanroepen:
Python: cdxgen -t python. Leest requirements-bestanden, Poetry en PDM. Vereist Java 21.
Java / Maven / Gradle: cdxgen -t java. Lost de volledige boom op, niet alleen de directe declaraties.
Node / npm: cdxgen -t javascript. Doorloopt de lockfile voor de echte transitieve grafiek.
Go: cdxgen -t go.
C / C++: cdxgen -t c. Java 21 vereist. Beste resultaten uit een echte build, niet uit een kale bronboom.
Containers: cdxgen -t docker alpine:3.20 -o bom.json. Haalt OS-pakketten en taalafhankelijkheden uit de image.
Wilt u dit in de CI opnemen? Controleer uw ecosysteem eerst tegen de lijst met ondersteunde projecttypen (Supported Project Types). De dekking is breed, niet universeel. Beter een hiaat vinden voordat een pipeline ervan afhankelijk is.
Bewijs van componentgebruik opnemen
Een basale SBOM somt op wat uw manifesten declareren. Dat is een bewering. Bewijs (evidence) is het bewijs. Voor een gereguleerde indiening telt dat verschil.
De flag --evidence (cdxgen 9.9 en later) legt vast waar elke component wordt gebruikt, niet alleen wat een manifest declareerde. Ga verder met call-stack-bewijs. Het toont of een kwetsbare functie bereikbaar is vanuit uw code.
Bereikbaarheid (reachability) verdient zichzelf terug. De meeste scanners markeren elke kwetsbare afhankelijkheid. Veel ervan zitten in codepaden die u nooit aanroept. Call-stack-bewijs laat zien welke bevindingen uw code daadwerkelijk raken. Dat is het verschil tussen een triagewachtrij van vierhonderd en een van twaalf.
SBOM ondertekenen
Een niet-ondertekende SBOM is een tekstbestand dat iedereen kan bewerken. Gaat hij naar een klant of toezichthouder? Onderteken hem.
Dat genereert een sleutelpaar en voegt een handtekening toe. Stroomafwaarts bevestigt cdx-verify dat het bestand sinds de ondertekening onveranderd is. Gebruik in productie uw eigen beheerde sleutels, niet een gegenereerd testpaar. Het mechanisme is ingebouwd. Zet het vroeg aan.
Opnemen in CI: GitHub Actions, Azure DevOps
GitHub Actions
Niets hiervan helpt als het eenmalig op een laptop draait. Maak het genereren een buildstap. Uit elke build hoort een SBOM te komen, net als een testrapport.
Een minimale GitHub Actions-job die de SBOM genereert en als artefact bewaart:
Twee dingen verdienen hun plaats. Java 21 vastzetten met setup-java voorkomt het stille vastlopen op oudere JDK's. bom.json als artefact uploaden bewaart het bestand na de run. Dat is het hele punt van genereren in de CI.
Pusht u naar een Dependency-Track-server? cdxgen dient direct in. Zet de URL en API-key als repository-secrets.
Azure Pipelines
Dezelfde job in Azure Pipelines. Zelfde vorm: Java 21 opzetten, cdxgen installeren, genereren, het bestand publiceren zodat het de agent overleeft.
Voor een gecontaineriseerde build vervangt u de install-en-run-regels door de Docker-image en koppelt u de workspace aan. Dat slaat de Node- en Java-setup over.
Valkuilen bij cdxgen-SBOM's
cdxgen produceert voor bijna alles een bestand. Of dat bestand volledig is, hangt af van het ecosysteem – en van de vraag of het project is gebouwd op het moment dat u scant. Dit treft teams die aannemen dat elke SBOM dezelfde diepte heeft.
De grootste hefboom is de build-levenscyclus. Standaard genereert cdxgen voor applicaties in de buildfase. De diepte hangt bij meerdere ecosystemen af van of het project eerst is hersteld (restored) of gebouwd. Scans vóór de build zijn in de CI sneller en veiliger. Ze kunnen echter de volledige transitieve boom missen. Weet in welke modus u zit.
Ecosysteem | Transitieve diepte | Wat het nodig heeft | Waarop te letten |
|---|---|---|---|
Java (Maven) | Volledig | Oplosbare POM; Maven is standaard vóór Gradle | Forceer Gradle met |
JavaScript / Node | Volledig | Aanwezige lockfile | Geen lockfile betekent alleen directe afhankelijkheden, een ondiepe BOM |
Python | Goed | Java 21 geïnstalleerd |
|
Go | Goed | Module-bewust project | Alleen-binair vereist |
.NET | Volledig pas na restore |
| Container-image bundelt SDK 8.0; een versieconflict laat de boom vervallen |
C / C++ | Gedeeltelijk | Een echte buildcontext, Java 21 | Een kale bronboom levert een dunne BOM; bouw eerst |
Rust, Ruby, PHP | Goed | Standaardmanifesten en lockfiles | Dekking solide; verifieer tegen uw project |
Gewoonten die de BOM volledig houden:
Geef altijd
-top. Automatische detectie werkt meestal. Als ze verkeerd raadt, is de BOM stilletjes onvolledig. Het type benoemen haalt het raden weg.Bouw of restore vóór het scannen bij .NET, C/C++ en alles wat de volledige boom nodig heeft. Een scan vóór de build is niet fout. Hij is ondieper. Weet welke u hebt uitgeleverd.
Controleer op een lockfile. Bij Node en dergelijke betekent geen lockfile alleen directe afhankelijkheden. Een BOM met alleen directe afhankelijkheden doorstaat een audit en verbergt daarbij het grootste deel van uw toeleveringsketen.
Valideer de uitvoer. cdxgen valideert standaard tegen het schema. Houd dat aan. Behandel een waarschuwing als een signaal om te kijken, niet als een over te slaan regel.
Zet de specificatieversie vast. Maak van
--spec-versioneen bewuste keuze. De versie die u uitgeeft, is de versie waartegen een klant of toezichthouder controleert.
Geen van deze punten is een reden om cdxgen te mijden. Ze zijn het verschil tussen een BOM die af lijkt en een die het is.
C/C++ en embedded: het lastigste geval
In de valkuilentabel staat C/C++ op „gedeeltelijk", omdat een generieke generator – cdxgen inbegrepen – in die ecosystemen het minste heeft om mee te werken. En de kloof tussen wat een tool rapporteert en wat daadwerkelijk wordt uitgeleverd, is hier de grootste van de branche.
De specifieke valkuilen:
Geen afhankelijkheidsmanifest als vertrekpunt. Node heeft een lockfile, Python heeft er een, Rust en Go hebben er een. C/C++ heeft niets vergelijkbaars. Conan, vcpkg en CMake FetchContent helpen wanneer ze worden gebruikt, maar de meeste embedded projecten bouwen met kale Makefiles, IAR of STM32CubeIDE, dus er is geen machineleesbare grafiek om te parsen.
Ingekopieerde broncode verdwijnt in uw boom. Bibliotheken als lwIP, mbedTLS of nlohmann/json worden rechtstreeks in het project gekopieerd, en eenmaal gekopieerd zien ze eruit als eigen code. Een generator die alleen manifesten leest, ziet ze nooit. Ze detecteren vereist fingerprinting tegen een corpus van bekende releases, en zodra de code is gepatcht, faalt exacte matching en zit u in fuzzy matching met echte onzekerheid.
Statische .a-archieven zijn bijna blackboxes. Een libfoo.a die maanden geleden uit ingekopieerde broncode is gebouwd, draagt een bestandsnaam en weinig anders. Geen leverancier, geen upstream-versie, geen van de NTIA-minimumelementen. Linker-inspectie met -l geeft u hooguit een naam, en embedded builds compileren RTOS, HAL en crypto vaak uit broncode zonder enige -l-flag.
Het inventariseren van de vendor-map telt te veel. Een gedeelde vendor/-map bevat veel bibliotheken, maar een enkel buildtarget gebruikt er slechts enkele. De hele map opsommen zet componenten in de SBOM die niet in de binary zitten, wat in elke stroomafwaartse kwetsbaarheidsscan tot valse positieven leidt. --gc-sections maakt dit erger: code die compileert maar nooit wordt aangeroepen, draagt nul bytes bij aan de image, maar een naïeve scan rapporteert hem toch.
Silicon-leverancier-SDK's voegen ruis toe. ST, NXP, TI en Renesas leveren geforkte, hernoemde, aangepaste kopieën van FreeRTOS, lwIP en mbedTLS binnen hun SDK's. Deze tegen upstream-releases fingerprinten is onbetrouwbaar zonder leveranciersspecifieke detectie.
Een accurate embedded C/C++-SBOM moet voortkomen uit wat de build daadwerkelijk compileert en linkt voor een specifiek doel, gecorreleerd met detectie van ingekopieerde code en platformbewustzijn. Die details kunnen alleen komen uit analyse tijdens de build, niet uit het parsen van manifesten – en dat valt buiten waarvoor cdxgen is gebouwd.
Dit is het probleem waar lynkctl, Interlynks SBOM-generator voor embedded C/C++, omheen is ontworpen: toolchain-bewuste extractie uit GNU Make, CMake en IAR, gekoppeld aan een gecureerde index van embedded open-sourcecomponenten voor de ingekopieerde laag. Als uw doel firmware is, begin daar in plaats van een generieke generator te dwingen een geval te dekken waarvoor hij nooit was bedoeld. Onze volledige uiteenzetting waarom dit moeilijk is, staat in „The State of SBOM Generation for C/C++".
Verder dan het genereren van SBOM's
Eén ding bepaalt nog of uw SBOM-programma standhoudt.
cdxgen is een generator. Het bekijkt één project, één image of één build en produceert een accuraat CycloneDX-bestand. Dat doet het goed. Elk commando hierboven is echt. Voor één codebase hebt u nu wat u nodig hebt.
Een generator beheert niet wat hij genereert. Dat is geen kritiek op cdxgen. Het is de categorie. Ga van één project naar een portfolio en er duikt een andere reeks problemen op. Geen daarvan is een generatieprobleem.
U produceert niet één SBOM. U produceert er duizenden – één per build per service per release. Ze stapelen zich sneller op dan iemand ze leest.
Verschillende teams geven verschillende formaten en versies uit. Dezelfde component krijgt op drie manieren een naam. Niets aggregeert netjes over producten heen.
Elke SBOM is een momentopname. Accuraat op buildtijd, blind voor de CVE die volgende week wordt geopenbaard. Een bestand op schijf controleert zichzelf niet opnieuw.
Ook leveranciers sturen SBOM's, in welke vorm ze maar willen. Die moeten worden gevalideerd en samengevoegd met uw eigen.
Het bestand genereren doorstaat de audit. De vraag „Waar zijn we blootgesteld, over alles heen wat we uitleveren, en wel nú?" beantwoorden is een ander systeem. Welke u hebt gebouwd, ontdekt u wanneer voor het eerst op een vrijdag een kritieke CVE inslaat.
Gebruik dus cdxgen. Het is de juiste tool voor de stap die het bezit. Dimensioneer die stap alleen correct. Genereren is het begin van een SBOM-programma, niet het geheel ervan.
Samenvatting
Installeer cdxgen. Voer cdxgen -t <type> --spec-version 1.6 -o bom.json uit. Voeg --evidence toe voor bewijs, en --with-reachables om kwetsbaarheidsruis te verminderen. Onderteken wat het pand verlaat. Verwerk het in GitHub Actions of Azure Pipelines zodat het bij elke build draait.
Let op de dieptevalkuilen. Geef -t expliciet op. Bouw of restore vóór het scannen van de ecosystemen die dat nodig hebben. Bevestig dat er een lockfile aanwezig is, anders levert u een BOM met alleen directe afhankelijkheden uit.
Dat geeft u accurate, actuele CycloneDX-bestanden. Een stapel bestanden omzetten in een antwoord dat u onder druk kunt vertrouwen, vergt de laag die erbovenop zit. Plan daarvoor voordat u het nodig hebt, niet erna.
Interlynk geeft security- en complianceteams één system of record voor elke SBOM – uit cdxgen of welke andere generator dan ook, intern of van leveranciers – met genormaliseerde componentidentiteit en ingebouwde continue monitoring. Houd elke uitvoer actueel terwijl uw afhankelijkheden en de openbaarmakingen evolueren, en beantwoord de portfoliobrede blootstellingsvraag in minuten in plaats van dagen. Vertrouwd door security- en complianceteams bij meer dan 100 gereguleerde bedrijven.