Moderne Java-Anwendungen bestehen längst nicht mehr nur aus eigenem Quellcode. Sie enthalten Frameworks, Libraries, Build-Plugins, transitive Abhängigkeiten und je nach Anwendung auch Frontend-Bestandteile. Gerade bei Webanwendungen mit Vaadin (https://3g3.eu/vdn) wird deutlich, wie produktiv Java-Entwicklung heute sein kann, aber auch, wie komplex die tatsächliche Softwarezusammensetzung im Hintergrund wird. Eine Software Bill of Materials, kurz SBOM, macht diese Zusammensetzung sichtbar und liefert eine maschinenlesbare Grundlage für Sicherheits-, Lizenz- und Release-Entscheidungen. Dieser Artikel zeigt, warum SBOMs für Java-Entwickler im Alltag relevant sind, wie sie mit Maven, Gradle und CycloneDX erzeugt werden können und warum die eigentliche Wirkung erst durch Auswertung entsteht. Als pragmatischer nächster Schritt wird gezeigt, wie eine erzeugte SBOM mit dem freien SBOM-Checker von Exodos Labs (https://3g3.eu/exodos-free-sbom) geprüft werden kann, um aus einer technischen Komponentenliste eine konkrete erste Risikosicht zu gewinnen.
Was steckt wirklich in meiner Java-Anwendung?
Wenn wir als Java-Entwickler über Sicherheit sprechen, denken wir häufig zuerst an Quellcode. Wir prüfen Eingaben, vermeiden SQL-Injection, härten REST-Endpunkte, achten auf Authentifizierung, Logging und saubere Fehlerbehandlung. All das ist wichtig. Trotzdem bleibt ein großer Teil unserer Anwendung oft erstaunlich unscharf: die Abhängigkeiten, aus denen sie zusammengesetzt ist.
Ein modernes Java-Projekt besteht selten nur aus dem Code, den wir selbst geschrieben haben. Es nutzt Bibliotheken, Frameworks, Build-Plugins, transitive Dependencies und manchmal zusätzlich Frontend-Pakete, die über den Build-Prozess in das fertige Artefakt einfließen. Gerade bei Webanwendungen, etwa mit einem modernen Java-Framework wie Vaadin (https://3g3.eu/vdn) , entsteht schnell ein komplexer Software-Baukasten. Auf den ersten Blick entwickeln wir eine Java-Anwendung. Tatsächlich liefern wir aber ein zusammengesetztes Produkt aus vielen einzelnen Komponenten aus.
Genau an dieser Stelle wird eine SBOM interessant. Eine Software Bill of Materials ist im Kern eine maschinenlesbare Zutatenliste der Software. Sie beschreibt, welche Komponenten in einer Anwendung enthalten sind, in welchen Versionen sie verwendet werden und in welcher Beziehung sie zueinander stehen. Für Entwickler klingt das zunächst vielleicht nach Compliance, Audit oder zusätzlicher Bürokratie. Der eigentliche Wert liegt aber viel näher am Alltag.
Eine SBOM hilft bei sehr praktischen Fragen: Bin ich von einer neu veröffentlichten Schwachstelle betroffen? Welche Version einer bestimmten Bibliothek steckt wirklich in meinem Release? Welche Lizenzen bringe ich durch meine Dependencies mit? Welche Komponenten stammen direkt aus meinem Projekt und welche wurden nur transitiv hineingezogen? Und wie kann ich einem Kunden, einem Security-Team oder einem Auditor nachvollziehbar erklären, was tatsächlich Bestandteil meiner Anwendung ist?
Eine SBOM macht eine Anwendung nicht automatisch sicherer. Aber sie macht sichtbar, worüber wir überhaupt sprechen müssen. Ohne Inventar bleibt Software-Supply-Chain-Sicherheit ein Bauchgefühl. Mit einer SBOM wird sie überprüfbar, analysierbar und schrittweise automatisierbar.
Was bringt mir eine SBOM als Java-Entwickler im Alltag?
Die erste Reaktion auf das Thema SBOM ist bei vielen Entwicklern eher zurückhaltend. Noch ein Artefakt. Noch ein Format. Noch ein Begriff aus der Welt von Compliance, Audit und Security-Governance. Gerade im Java-Alltag, in dem ohnehin schon Build-Prozesse, Tests, Deployments, Dependency-Updates und Framework-Versionen gepflegt werden müssen, klingt eine Software Bill of Materials zunächst nach zusätzlicher Arbeit.
Der eigentliche Nutzen einer SBOM zeigt sich jedoch nicht in der Theorie, sondern in konkreten Alltagssituationen. Eine neue Schwachstelle wird veröffentlicht. Plötzlich steht die Frage im Raum, ob die eigene Anwendung betroffen ist. Oft beginnt dann eine hektische Suche: Welche Version dieser Bibliothek verwenden wir? Ist sie direkt eingebunden oder kommt sie transitiv über eine andere Dependency? Ist die betroffene Komponente überhaupt Bestandteil des produktiven Artefakts? Gibt es mehrere Anwendungen, in denen diese Bibliothek verwendet wird? Und welche Releases müssen jetzt wirklich geprüft oder aktualisiert werden?
Ohne SBOM wird diese Analyse schnell manuell. Man sucht in pom.xml-Dateien, Gradle-Konfigurationen, Dependency-Trees, Build-Logs, Container-Images oder internen Dokumentationen. Das funktioniert in kleinen Projekten manchmal noch ausreichend gut. Sobald aber mehrere Services, mehrere Teams, mehrere Release-Stände oder mehrere Kundeninstallationen beteiligt sind, wird die Suche unzuverlässig. Man findet dann nicht mehr zwingend die Wahrheit über ein bestimmtes Release, sondern nur eine Momentaufnahme des aktuellen Quellcodes.
Genau hier liegt einer der wichtigsten praktischen Vorteile einer SBOM. Sie beschreibt nicht nur, was theoretisch im Projekt konfiguriert ist, sondern was zu einem bestimmten Zeitpunkt als Softwarebestandteil dokumentiert wurde. Damit wird sie zu einem Inventar des jeweiligen Builds oder Releases. Für Entwickler bedeutet das: Die Frage „Sind wir betroffen?“ lässt sich schneller, reproduzierbarer und nachvollziehbarer beantworten.
Das ist besonders im Java-Umfeld relevant, weil Abhängigkeiten selten isoliert betrachtet werden können. Eine Anwendung nutzt vielleicht nur wenige direkt deklarierte Libraries. Diese bringen aber weitere transitive Dependencies mit. Zusätzlich können Frameworks, Build-Plugins, Annotation Processor, Testwerkzeuge oder Frontend-Bestandteile in den Entwicklungs- und Build-Prozess hineinspielen. Eine moderne Java-Webanwendung, beispielsweise mit Vaadin, sieht im Quellcode oft angenehm fokussiert aus. Unter der Oberfläche entsteht jedoch ein komplexer Abhängigkeitsgraph aus Java-Artefakten, Build-Werkzeugen und je nach Projekt auch Frontend-Paketen.
Eine SBOM macht diesen Graphen nicht automatisch ungefährlich. Aber sie macht ihn sichtbar. Und Sichtbarkeit ist die Voraussetzung für jede belastbare Sicherheitsentscheidung. Ohne Inventar kann ein Team nur vermuten, welche Komponenten im Einsatz sind. Mit einer SBOM kann es prüfen, vergleichen und priorisieren.
Der Nutzen beschränkt sich dabei nicht auf Schwachstellen. Auch Lizenzfragen werden greifbarer. Welche Open-Source-Lizenzen gelangen über direkte und transitive Dependencies in das Produkt? Gibt es Komponenten, deren Lizenzmodell nicht zur geplanten Nutzung passt? Welche Bibliotheken wurden über Jahre nicht aktualisiert? Welche Komponenten tauchen plötzlich neu in einem Release auf? Solche Fragen lassen sich ohne strukturierte Komponentenliste nur schwer systematisch beantworten.
Eine SBOM hilft außerdem in der Kommunikation. Wenn ein Kunde, ein internes Security-Team oder ein Auditor wissen möchte, welche Softwarebestandteile in einer Anwendung enthalten sind, muss die Antwort nicht mehr aus manuell zusammenkopierten Listen bestehen. Stattdessen kann auf ein maschinenlesbares, versioniertes Artefakt verwiesen werden. Das ersetzt nicht die fachliche Bewertung, aber es schafft eine gemeinsame Grundlage.
Für Entwickler ist genau das der entscheidende Perspektivwechsel: Eine SBOM ist nicht nur ein Dokument für andere. Sie ist ein Werkzeug für das eigene Team. Sie hilft, Abhängigkeiten bewusster zu verwalten, Release-Entscheidungen besser zu begründen und Risiken schneller einzuordnen. Im Alltag geht es nicht darum, möglichst viele SBOM-Dateien zu produzieren. Es geht darum, bei kritischen Fragen nicht mehr im Nebel zu stehen.
Eine gute SBOM beantwortet nicht jede Sicherheitsfrage. Sie sagt nicht automatisch, ob eine Schwachstelle in der konkreten Anwendung ausnutzbar ist. Sie ersetzt keinen Code-Review, keine Tests und keine Architekturarbeit. Aber sie liefert eine belastbare Ausgangsbasis. Sie zeigt, welche Komponenten überhaupt betrachtet werden müssen. Damit wird sie zu einem praktischen Werkzeug für Software-Supply-Chain-Sicherheit im Java-Alltag.
SBOM kurz erklärt: Die maschinenlesbare Zutatenliste
Eine SBOM, also eine Software Bill of Materials, ist im einfachsten Sinne eine strukturierte Liste der Bestandteile einer Software. Der Vergleich mit einer Zutatenliste ist naheliegend: Wer ein fertiges Produkt betrachtet, sieht zunächst nur das Ergebnis. Erst die Zutatenliste zeigt, woraus dieses Produkt tatsächlich besteht. Bei Software ist es ähnlich. Eine Anwendung wirkt nach außen wie ein geschlossenes System. Tatsächlich besteht sie aus vielen einzelnen Komponenten, die zusammengebaut, verlinkt, paketiert und ausgeliefert werden.
Für Java-Entwickler ist dieser Gedanke besonders vertraut, auch wenn der Begriff SBOM vielleicht zunächst fremd wirkt. Schon eine einfache Anwendung besteht nicht nur aus eigenen Klassen. Sie enthält Abhängigkeiten aus Maven Central oder anderen Repositories, Framework-Komponenten, Hilfsbibliotheken, Build-Plugins und häufig weitere transitive Dependencies. Diese transitiven Abhängigkeiten sind besonders wichtig, weil sie nicht direkt im eigenen Quelltext oder in der ersten Ebene der pom.xml sichtbar sein müssen. Sie gelangen über andere Libraries in das Projekt und werden trotzdem Bestandteil des Softwareprodukts.
Eine SBOM macht diese Zusammensetzung explizit. Sie beschreibt, welche Komponenten vorhanden sind, welche Versionen verwendet werden und wie diese Komponenten miteinander zusammenhängen. Damit wird aus einem diffusen Abhängigkeitsgefühl ein konkretes Inventar. Dieses Inventar kann von Menschen gelesen, vor allem aber von Werkzeugen verarbeitet werden. Genau darin liegt der Unterschied zu einer manuell gepflegten Liste in einem Wiki oder einer README-Datei. Eine SBOM ist nicht nur Dokumentation, sondern ein maschinenlesbares Artefakt.
Typische Informationen in einer SBOM sind der Name einer Komponente, ihre Version, ihr Typ, ihre Herkunft, mögliche Lizenzinformationen und technische Identifikatoren. Je nach Format und Erzeugungswerkzeug können auch Hashwerte, Package URLs, Beziehungen zwischen Komponenten oder Metadaten zum Build enthalten sein. Nicht jede SBOM enthält alle Informationen in gleicher Qualität. Aber das Ziel bleibt gleich: Die verwendeten Softwarebestandteile sollen eindeutig und nachvollziehbar beschrieben werden.
Wichtig ist dabei die Abgrenzung: Eine SBOM ist noch keine Sicherheitsbewertung. Sie sagt zunächst nicht automatisch, ob eine Komponente gefährlich ist, ob eine Schwachstelle tatsächlich ausnutzbar ist oder ob eine Lizenz im konkreten Geschäftsmodell problematisch wird. Eine SBOM ist zuerst das Inventar. Die Bewertung entsteht erst im nächsten Schritt, wenn dieses Inventar mit Schwachstellendatenbanken, Lizenzregeln, internen Policies oder Risikoanalysen abgeglichen wird.
Gerade deshalb ist die SBOM so wertvoll. Ohne Inventar kann keine belastbare Bewertung stattfinden. Wer nicht weiß, welche Komponenten in einem Release enthalten sind, kann auch nicht zuverlässig beurteilen, ob dieses Release von einer neuen Schwachstelle betroffen ist. Wer nicht weiß, welche Lizenzen über direkte und transitive Dependencies eingebracht werden, kann Lizenzrisiken nur unvollständig bewerten. Und wer nicht weiß, welche Komponenten sich zwischen zwei Releases verändert haben, kann Änderungen in der Software-Supply-Chain kaum nachvollziehen.
Im Java-Umfeld gibt es zusätzlich eine kleine begriffliche Falle. Viele Entwickler kennen bereits den Begriff BOM aus Maven. Eine Maven BOM, also eine Bill of Materials im Sinne des Dependency Managements, dient dazu, Versionen von Abhängigkeiten zentral zu steuern. Sie hilft also beim Verwalten von Dependency-Versionen während der Entwicklung. Eine Security- oder Supply-Chain-SBOM verfolgt einen anderen Zweck. Sie beschreibt, welche Komponenten tatsächlich Bestandteil einer konkreten Software oder eines konkreten Releases sind. Beide Konzepte haben mit Abhängigkeiten zu tun, aber sie beantworten unterschiedliche Fragen.
Eine Maven BOM sagt vereinfacht: Diese Versionen sollen in einem Projekt verwendet werden. Eine SBOM sagt: Diese Komponenten sind in diesem konkreten Artefakt oder Release enthalten. Für den Alltag ist diese Unterscheidung wichtig. Bei einer Sicherheitsanalyse interessiert nicht nur, was geplant oder konfiguriert war, sondern was tatsächlich ausgeliefert wurde.
Eine SBOM ist damit ein technisches Bindeglied zwischen Entwicklung, Security, Betrieb und gegebenenfalls Kunden oder Auditoren. Entwicklungsteams erhalten ein präziseres Bild ihrer Abhängigkeiten. Security-Teams können Risiken systematischer bewerten. Der Betrieb kann nachvollziehen, welche Komponenten in produktiven Versionen stecken. Und Kunden erhalten bei Bedarf eine belastbarere Antwort als eine manuell gepflegte Komponentenliste.
Der Nutzen entsteht jedoch erst, wenn die SBOM nicht als statisches Dokument verstanden wird. Sie sollte an ein konkretes Artefakt, einen Build oder ein Release gebunden sein. Nur dann kann sie später noch erklären, welche Bestandteile zu diesem Zeitpunkt wirklich relevant waren. Eine SBOM ist also weniger ein Formular und mehr ein technisches Protokoll der Softwarezusammensetzung.
Für Java-Entwickler bedeutet das: Eine SBOM ist kein Fremdkörper im Entwicklungsprozess. Sie ist eine konsequente Erweiterung dessen, was Maven, Gradle und moderne Build-Pipelines ohnehin bereits tun. Der Build weiß, welche Abhängigkeiten aufgelöst wurden. Die SBOM macht dieses Wissen explizit, speicherbar, überprüfbar und austauschbar.
Warum Java-Projekte schnell unübersichtlich werden
Java-Projekte haben eine angenehme Eigenschaft: Sie lassen sich sehr strukturiert bauen. Maven und Gradle beschreiben Abhängigkeiten, Plugins, Module, Profile, Artefakte und Build-Schritte in einer Form, die für Entwickler gut handhabbar ist. Genau diese Stärke kann aber auch dazu führen, dass die tatsächliche Zusammensetzung einer Anwendung unterschätzt wird. Was im Projekt zunächst wie eine überschaubare Liste von Dependencies aussieht, entwickelt sich im Build zu einem deutlich größeren Abhängigkeitsgraphen.
Der Grund dafür liegt vor allem in transitiven Dependencies. Eine Bibliothek bringt weitere Bibliotheken mit. Diese bringen wiederum eigene Abhängigkeiten mit. Das ist im Alltag gewollt und praktisch, weil Entwickler nicht jede technische Einzelkomponente manuell verwalten müssen. Gleichzeitig entsteht dadurch aber eine Lieferkette, die nicht mehr vollständig auf der ersten Ebene der Projektkonfiguration sichtbar ist. In der pom.xml oder im Gradle-Buildfile stehen vielleicht nur wenige direkte Abhängigkeiten. Im fertigen Artefakt oder im effektiven Klassenpfad befinden sich jedoch deutlich mehr Komponenten.
Dieses Verhalten ist nicht automatisch problematisch. Es ist ein zentraler Bestandteil des Java-Ökosystems. Maven Central, semantische Versionierung, Dependency Management, BOMs, Plugins und etablierte Frameworks haben Java über Jahre hinweg produktiv gemacht. Das Problem entsteht erst dann, wenn diese Mechanismen als hinreichende Transparenz missverstanden werden. Eine deklarierte Dependency ist nicht dasselbe wie ein vollständiges Inventar der ausgelieferten Software.
Gerade in größeren Projekten wird diese Unterscheidung wichtig. Ein Team verwendet vielleicht ein Framework, ein Logging-System, eine JSON-Bibliothek, einen HTTP-Client, eine Persistenzschicht, Testwerkzeuge und verschiedene Build-Plugins. Jede dieser Komponenten kann eigene Abhängigkeiten einbringen. Zusätzlich gibt es häufig unterschiedliche Profile für Entwicklung, Test, Staging und Produktion. Was lokal im Entwicklungsmodus vorhanden ist, muss nicht identisch mit dem sein, was später in einem produktiven Release ausgeliefert wird.
Hinzu kommt, dass Java-Anwendungen heute selten reine Backend-Artefakte sind. Moderne Webanwendungen kombinieren Backend-Code, UI-Komponenten, Build-Tooling und teilweise Frontend-Abhängigkeiten. Eine Vaadin-Anwendung ist dafür ein gutes Beispiel. Entwickler schreiben primär Java und können sehr produktiv serverseitige UIs bauen. Gleichzeitig existiert unter der Oberfläche ein Build-Prozess, der weitere technische Bestandteile einbeziehen kann. Dadurch entsteht eine Anwendung, die aus Sicht des Entwicklers angenehm geschlossen wirkt, aus Sicht der Software-Supply-Chain aber aus vielen einzelnen Bausteinen besteht.
Auch Multi-Modul-Projekte erhöhen die Komplexität. Ein Modul enthält Kernlogik, ein anderes stellt REST-Endpunkte bereit, ein weiteres enthält UI-Code, ein weiteres gemeinsame Datenmodelle oder interne Utilities. Jedes Modul kann eigene Abhängigkeiten besitzen. Zusätzlich können interne Bibliotheken verwendet werden, die selbst wieder externe Dependencies einbringen. In solchen Architekturen reicht es nicht aus, nur eine einzelne Datei im Projekt zu betrachten. Relevant ist die Zusammensetzung des konkreten Builds.
Ein weiterer Punkt ist die zeitliche Dimension. Abhängigkeiten verändern sich. Eine Version wird aktualisiert, eine transitive Dependency wird durch ein neues Release ausgetauscht, ein Plugin bringt eine neue Version einer Hilfsbibliothek mit, ein Framework passt seine internen Dependencies an. Solche Änderungen können fachlich völlig unauffällig sein und trotzdem sicherheitsrelevant werden. Ohne strukturiertes Inventar ist es schwierig, später nachzuvollziehen, welche Komponenten in welchem Release tatsächlich enthalten waren.
Für Entwickler zeigt sich das häufig erst im Ernstfall. Eine neue Schwachstelle wird bekannt und plötzlich muss geklärt werden, ob eine bestimmte Bibliothek irgendwo in der Anwendung steckt. Der direkte Blick in die Projektdateien liefert nicht immer eine eindeutige Antwort. Vielleicht ist die Bibliothek nicht direkt deklariert, sondern kommt transitiv über ein Framework. Vielleicht wurde sie nur in einer älteren Release-Version verwendet. Vielleicht ist sie im aktuellen Entwicklungsstand bereits aktualisiert, aber in einer produktiven Kundeninstallation noch vorhanden. Genau diese Fragen sind ohne sauberes Komponenteninventar schwer zuverlässig zu beantworten.
Eine SBOM hilft, diese Unübersichtlichkeit zu reduzieren. Sie ersetzt nicht das Verständnis des Build-Systems, aber sie macht das Ergebnis des Build-Systems sichtbarer. Statt nur auf die Absicht in der Projektkonfiguration zu schauen, dokumentiert sie die tatsächliche Zusammensetzung eines Artefakts oder Releases. Damit wird der Abhängigkeitsgraph nicht nur ein temporäres Ergebnis des Build-Tools, sondern ein speicherbares und analysierbares Artefakt.
Das ist besonders wichtig, weil Sicherheitsentscheidungen selten auf Basis von Vermutungen getroffen werden sollten. Wenn ein Team entscheiden muss, ob ein Release zurückgezogen, aktualisiert oder weiter betrieben werden kann, braucht es belastbare Informationen. Eine SBOM liefert dafür eine Grundlage. Sie zeigt, welche Komponenten betrachtet werden müssen, welche Versionen im Spiel sind und welche Beziehungen zwischen ihnen bestehen können.
Java-Projekte sind deshalb besonders gute Kandidaten für SBOMs. Nicht weil Java unsicherer wäre als andere Ökosysteme, sondern weil Java-Projekte häufig stark von wiederverwendbaren Komponenten, Build-Automatisierung und etabliertem Dependency Management profitieren. Genau dort, wo Wiederverwendung und Automatisierung stark sind, wird Transparenz über die tatsächliche Softwarezusammensetzung besonders wertvoll.
Die entscheidende Erkenntnis lautet: Maven und Gradle helfen uns, Software zu bauen. Eine SBOM hilft uns, die gebaute Software nachvollziehbar zu beschreiben. Beides gehört zusammen. Erst wenn die aufgelösten Abhängigkeiten eines konkreten Builds sichtbar werden, kann aus Dependency Management auch belastbare Software-Supply-Chain-Transparenz entstehen.
Was steht eigentlich in einer SBOM?
Nachdem klar ist, warum Java-Projekte schnell unübersichtlich werden können, stellt sich die nächste naheliegende Frage: Was steht in einer SBOM eigentlich konkret drin? Die einfache Antwort lautet: eine strukturierte Beschreibung der Softwarebestandteile. Die etwas genauere Antwort ist interessanter, weil sie zeigt, warum eine SBOM mehr ist als eine exportierte Dependency-Liste aus Maven oder Gradle.
Eine SBOM beschreibt Komponenten. Das können Bibliotheken, Frameworks, Module, Pakete oder andere Softwarebestandteile sein, die in einem Projekt verwendet werden. Für eine Java-Anwendung sind das typischerweise JAR-Artefakte, interne Module, externe Open-Source-Bibliotheken und je nach Anwendung auch weitere Bestandteile aus dem Build- oder Frontend-Umfeld. Entscheidend ist nicht nur, dass eine Komponente irgendwo im Projekt vorkommt, sondern dass sie als Bestandteil eines konkreten Builds oder Releases dokumentiert wird.
Zu jeder Komponente gehört mindestens ein Name. Dieser Name allein reicht jedoch selten aus. Viele Bibliotheken haben ähnliche Namen, wechseln über die Zeit ihre Artefaktstruktur oder existieren in unterschiedlichen Ökosystemen. Deshalb ist die Version ebenso wichtig. Erst die Kombination aus Name und Version macht eine Komponente wirklich analysierbar. Bei einer Sicherheitsmeldung ist fast nie nur entscheidend, ob eine Bibliothek verwendet wird, sondern welche Version davon tatsächlich im Einsatz ist.
Im Java-Umfeld kommen zusätzlich Koordinaten ins Spiel. Maven-Artefakte werden üblicherweise über groupId, artifactId und version identifiziert. Diese Informationen sind für Entwickler vertraut und bilden eine gute Grundlage, um eine Komponente eindeutig zuzuordnen. Eine SBOM kann solche Informationen aufnehmen und in eine Form bringen, die auch außerhalb des Build-Tools ausgewertet werden kann. Damit wird aus einer Java-spezifischen Dependency-Information ein allgemeineres Analyseartefakt.
Ein weiterer wichtiger Bestandteil sind Lizenzinformationen. Viele Abhängigkeiten stammen aus Open-Source-Projekten. Das ist eine große Stärke des Java-Ökosystems, bringt aber auch Verantwortung mit sich. Eine SBOM kann festhalten, welche Lizenzen mit den verwendeten Komponenten verbunden sind. Das bedeutet nicht automatisch, dass jede Lizenzinformation vollständig oder juristisch abschließend bewertet ist. Aber sie schafft einen Ausgangspunkt, um Lizenzrisiken frühzeitig zu erkennen und nicht erst kurz vor einer Auslieferung darüber zu stolpern.
Auch technische Identifikatoren spielen eine Rolle. Dazu können Package URLs, kurz purl, gehören. Eine Package URL beschreibt eine Komponente so, dass sie über verschiedene Ökosysteme hinweg maschinenlesbar identifiziert werden kann. Für eine Maven-Komponente kann dadurch beispielsweise klarer beschrieben werden, aus welchem Paketökosystem sie stammt und welche konkreten Koordinaten sie besitzt. Solche Identifikatoren sind besonders nützlich, wenn eine SBOM von externen Analysewerkzeugen verarbeitet wird.
Hashwerte können ebenfalls Teil einer SBOM sein. Sie dienen dazu, konkrete Artefakte eindeutiger zu identifizieren. Während Name und Version beschreiben, was eine Komponente sein soll, kann ein Hashwert helfen, ein bestimmtes Artefakt technisch wiederzuerkennen. Das ist vor allem dann relevant, wenn Integrität, Reproduzierbarkeit oder spätere Nachvollziehbarkeit wichtig werden. Für den Einstieg muss man Hashwerte nicht überbewerten, aber sie zeigen, dass eine SBOM mehr leisten kann als eine einfache Namensliste.
Besonders wertvoll sind die Beziehungen zwischen Komponenten. Eine moderne Anwendung besteht nicht nur aus einer flachen Menge von Bibliotheken. Es gibt direkte und transitive Abhängigkeiten. Eine gute SBOM kann solche Beziehungen abbilden. Dadurch wird sichtbar, ob eine problematische Bibliothek direkt eingebunden wurde oder über einen anderen Bestandteil in das Projekt gelangt ist.
Diese Beziehungsinformationen sind im Alltag sehr hilfreich. Wenn eine Schwachstelle in einer transitiven Dependency auftaucht, reicht die Information „Bibliothek X ist vorhanden“ oft nicht aus. Interessant ist auch, warum sie vorhanden ist. Kommt sie über ein Framework? Über ein Logging-System? Über einen HTTP-Client? Über ein Testwerkzeug? Diese Information entscheidet darüber, wie ein Team sinnvoll reagiert. Manchmal reicht ein Update einer direkten Dependency. Manchmal muss eine transitive Version überschrieben werden. Manchmal stellt sich heraus, dass die betroffene Komponente nur in einem nicht produktiven Kontext verwendet wird.
Neben den Komponenten selbst enthält eine SBOM häufig Metadaten. Dazu gehören Informationen darüber, wann die SBOM erzeugt wurde, welches Werkzeug sie erzeugt hat, auf welches Projekt oder Artefakt sie sich bezieht und in welchem Format sie vorliegt. Diese Metadaten wirken unscheinbar, sind aber wichtig. Eine SBOM ohne klaren Bezug zu einem Build, einem Release oder einem Artefakt verliert schnell an Aussagekraft. Später muss nachvollziehbar sein, welche SBOM zu welcher ausgelieferten Version gehört.
Für Java-Entwickler ist außerdem wichtig, dass eine SBOM nicht zwingend nur Runtime-Abhängigkeiten enthalten muss. Je nach Werkzeug, Konfiguration und Zielsetzung können auch Build-Time-, Test- oder Entwicklungsabhängigkeiten auftauchen. Das ist nicht falsch, muss aber verstanden werden. Eine SBOM ist nur dann nützlich, wenn klar ist, welchen Ausschnitt der Software sie beschreibt. Geht es um das produktive Artefakt? Um den vollständigen Build? Um ein Container-Image? Oder um das gesamte Repository? Diese Frage sollte bewusst beantwortet werden.
Das bedeutet auch: Nicht jede SBOM ist automatisch gleich gut. Zwei Werkzeuge können für dasselbe Projekt unterschiedliche Ergebnisse liefern, weil sie unterschiedliche Quellen betrachten oder andere Detailgrade erzeugen. Eine SBOM ist deshalb kein magisches Wahrheitsdokument. Sie ist ein technisches Artefakt, dessen Qualität davon abhängt, wie es erzeugt wurde, welche Datenquellen verwendet wurden und ob es zum betrachteten Release passt.
Trotzdem ist der praktische Wert groß. Schon eine einfache SBOM kann deutlich mehr Transparenz schaffen als eine manuell gepflegte Liste. Sie macht sichtbar, welche Komponenten vorhanden sind, welche Versionen verwendet werden, welche Lizenzen auftreten und welche Abhängigkeiten miteinander verbunden sind. Damit entsteht eine Grundlage, die später automatisiert geprüft, verglichen und bewertet werden kann.
Für den Alltag reicht zunächst ein pragmatischer Blick: Eine SBOM beantwortet die Frage, woraus meine Anwendung besteht. Je besser sie Komponenten, Versionen, Lizenzen, Identifikatoren, Beziehungen und Metadaten beschreibt, desto wertvoller wird sie für Sicherheitsanalysen, Lizenzprüfungen und Release-Entscheidungen. Genau deshalb ist sie für Java-Entwickler nicht nur ein Compliance-Artefakt, sondern ein Werkzeug zur technischen Selbstaufklärung.
SBOM erzeugen: Maven, Gradle und CycloneDX
Nachdem klar ist, welche Informationen eine SBOM enthalten kann, stellt sich die praktische Frage: Wie kommt man als Java-Entwickler überhaupt an eine solche Datei? Die gute Nachricht ist, dass der Einstieg deutlich einfacher ist, als der Begriff zunächst vermuten lässt. In vielen Java-Projekten muss keine eigene Infrastruktur aufgebaut werden. Die benötigten Informationen liegen bereits im Build-System vor. Maven oder Gradle wissen, welche Abhängigkeiten aufgelöst werden, welche Versionen verwendet werden und welche Artefakte in den Build einfließen. Eine SBOM macht dieses Wissen explizit und speichert es in einem standardisierten Format.
Für Java-Projekte ist CycloneDX ein sehr pragmatischer Einstieg. CycloneDX ist ein verbreitetes SBOM-Format, das sich gut für die Software-Supply-Chain-Sicherheit, die Dependency-Analyse und die automatisierte Auswertung eignet. Wichtig ist dabei weniger die Formatreligion, sondern der praktische Nutzen: Eine CycloneDX-SBOM kann von vielen Werkzeugen erzeugt, gelesen und analysiert werden. Für Entwickler bedeutet das, dass die SBOM nicht in einem proprietären Einzelformat endet, sondern als technisches Austauschformat weiterverarbeitet werden kann.
Im Maven-Umfeld wird eine SBOM typischerweise über ein Plugin erzeugt. Das Plugin analysiert die Projektstruktur, die aufgelösten Dependencies sowie, je nach Konfiguration, auch Module und transitive Abhängigkeiten. Das Ergebnis ist eine Datei, häufig im JSON- oder XML-Format, die die Bestandteile des Projekts beschreibt. Für den ersten Einstieg reicht meist eine lokale Generierung aus. Der Entwickler erzeugt die SBOM, öffnet sie in einem Editor oder gibt sie an ein Analysewerkzeug weiter. Schon dieser Schritt zeigt häufig mehr über das Projekt, als im Alltag bewusst wahrgenommen wird.
Für ein Maven-Projekt kann die Einbindung beispielsweise so aussehen. Die konkrete Plugin-Version sollte im Projekt bewusst festgelegt und regelmäßig geprüft werden. Entscheidend ist hier der Mechanismus: Die SBOM wird im Build erzeugt und landet als Artefakt im target-Verzeichnis.
<properties>
<cyclonedx.maven.plugin.version>2.9.1</cyclonedx.maven.plugin.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.cyclonedx</groupId>
<artifactId>cyclonedx-maven-plugin</artifactId>
<version>${cyclonedx.maven.plugin.version}</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>makeAggregateBom</goal>
</goals>
</execution>
</executions>
<configuration>
<projectType>application</projectType>
<schemaVersion>1.6</schemaVersion>
<includeCompileScope>true</includeCompileScope>
<includeProvidedScope>true</includeProvidedScope>
<includeRuntimeScope>true</includeRuntimeScope>
<includeSystemScope>true</includeSystemScope>
<includeTestScope>false</includeTestScope>
<includeLicenseText>false</includeLicenseText>
<outputFormat>json</outputFormat>
<outputName>bom</outputName>
<outputDirectory>${project.build.directory}</outputDirectory>
</configuration>
</plugin>
</plugins>
</build>
Für viele Anwendungen ist makeAggregateBom der passende Einstieg, weil damit eine aggregierte SBOM für das Projekt beziehungsweise für einen Multi-Modul-Build erzeugt werden kann. In einem sehr einfachen Einzelmodul-Projekt kann auch makeBom ausreichend sein. Der Unterschied ist für den Artikel wichtig: makeBom betrachtet das jeweilige Maven-Modul, während makeAggregateBom eine übergreifende Sicht auf den Build erzeugt werden kann.
Die wichtigsten Konfigurationspunkte werden kurz erläutert. Mit schemaVersion wird festgelegt, welche CycloneDX-Schema-Version erzeugt wird. Mit outputFormat kann gesteuert werden, ob JSON, XML oder beides erzeugt wird. Für die spätere Analyse ist JSON häufig angenehm, weil viele Werkzeuge dieses Format direkt verarbeiten. Die Scope-Schalter bestimmen, welche Maven-Scopes in die SBOM aufgenommen werden. Für eine erste produktionsnahe Betrachtung ist es meistens sinnvoll, Test-Abhängigkeiten nicht aufzunehmen und sich auf Compile-, Provided- und Runtime-Abhängigkeiten zu konzentrieren.
Nach der Einbindung kann die SBOM ganz normal über den Maven-Build erzeugt werden:
mvn clean package
Das Ergebnis liegt dann beispielsweise als target/bom.json vor. Diese Datei ist das eigentliche SBOM-Artefakt und kann anschließend geprüft, archiviert oder an ein Analysewerkzeug übergeben werden.
Bei Gradle ist der Gedanke ähnlich. Auch dort wird die SBOM nicht manuell erstellt, sondern aus dem Build heraus erzeugt. Das ist entscheidend. Eine manuell gepflegte Komponentenliste veraltet schnell. Eine aus dem Build generierte SBOM hat hingegen einen direkten Bezug zum tatsächlichen Projektzustand. Sie kann wiederholt erzeugt, als Teil des Build-Prozesses und später zusammen mit anderen Release-Artefakten abgelegt werden.
Wichtig ist, den Scope bewusst zu wählen. Soll die SBOM die Anwendung beschreiben, wie sie produktiv bereitgestellt wird? Soll sie alle Module des Projekts umfassen? Sollen Test-Dependencies enthalten sein oder nicht? Geht es um eine Library, einen Server, eine Webanwendung oder ein vollständiges Deployment-Artefakt? Diese Fragen sind nicht akademisch. Eine SBOM ist nur dann hilfreich, wenn klar ist, was sie tatsächlich beschreibt. Für den Start ist es sinnvoll, sich auf das produktive Artefakt oder den Release-Build zu konzentrieren.
Gerade bei Multi-Modul-Projekten sollte man genauer hinschauen. Eine Anwendung kann aus mehreren Maven- oder Gradle-Modulen bestehen: Core-Logik, Server-Komponente, UI-Modul, gemeinsame Modelle oder interne Hilfsbibliotheken. Je nach Tooling kann eine SBOM pro Modul oder eine aggregierte SBOM für das Gesamtprojekt erzeugt werden. Beides kann sinnvoll sein. Für die Sicherheitsbewertung eines ausgelieferten Produkts ist meistens die aggregierte Sicht besonders wertvoll, weil sie die tatsächliche Zusammensetzung des Gesamtartefakts sichtbar macht.
Für den Entwickleralltag ist das ein großer Vorteil. Man muss nicht sofort eine vollständige Governance-Plattform einführen, um Nutzen zu erzeugen. Schon ein lokaler Ablauf kann reichen: Projekt bauen, SBOM erstellen, Datei prüfen, erste Auffälligkeiten analysieren. Danach kann der Prozess schrittweise erweitert werden. Erst lokal, dann im Build, später in der Pipeline und schließlich als fester Bestandteil jedes Releases.
Bei Vaadin-Anwendungen ist dieser Ansatz besonders anschaulich. Eine Vaadin-Anwendung wird von Java-Entwicklern häufig primär als Java-Projekt wahrgenommen. Das stimmt aus Entwicklungssicht auch. Gleichzeitig entsteht im Build ein Artefakt, das neben dem eigenen Code und den Vaadin-Abhängigkeiten weitere Bestandteile enthalten kann. Eine SBOM hilft dabei, diese Zusammensetzung transparenter zu machen. Dadurch wird klarer, welche Komponenten tatsächlich Teil der Anwendung sind und welche nur während der Entwicklung oder des Builds eine Rolle spielen.
Ein pragmatischer Arbeitsablauf könnte deshalb so aussehen: Zuerst wird die Anwendung wie gewohnt entwickelt. Danach wird mithilfe von Maven oder Gradle eine CycloneDX-SBOM erzeugt. Diese SBOM wird als JSON-Datei gespeichert und an ein Analysewerkzeug übergeben. Dadurch entsteht aus der abstrakten Dependency-Landschaft ein konkretes, prüfbares Inventar. Genau dieser Übergang ist entscheidend. Die SBOM soll nicht nur erzeugt werden, damit sie existiert. Sie soll verwendet werden, um bessere Entscheidungen zu treffen.
Für den Einstieg sollte man die Anforderungen bewusst klein halten. Es geht nicht darum, alle Sonderfälle sofort perfekt abzudecken. Viel wichtiger ist, dass die SBOM reproduzierbar erzeugt wird, dem richtigen Artefakt zugeordnet ist und in einem Format vorliegt, das andere Werkzeuge verstehen. Wenn dieser erste Schritt funktioniert, kann das Team später Qualitätskriterien, Automatisierung, Release-Vergleiche oder Richtlinien ergänzen.
Damit wird die SBOM-Erzeugung zu einem normalen Bestandteil des Java-Builds. Sie ist kein separater manueller Dokumentationsschritt, sondern ein weiteres Build-Artefakt. So wie Tests-Ergebnisse erzeugt werden, Code Coverage gemessen werden kann oder ein JAR gebaut wird, kann auch eine SBOM entstehen. Der Unterschied ist: Dieses Artefakt beschreibt nicht das Verhalten der Anwendung, sondern ihre Zusammensetzung.
Genau darin liegt der praktische Wert. Maven und Gradle lösen Abhängigkeiten auf, bauen Artefakte und strukturieren Projekte. CycloneDX erstellt daraus eine maschinenlesbare Beschreibung der Softwarelieferkette. Für Java-Entwickler entsteht dadurch ein sehr niedriger Einstiegspunkt in SBOMs: nicht über lange Richtliniendokumente, sondern über den eigenen Build.
Im nächsten Teil geht es dann an die praktische Analyse.. stay tuned