Grundschutz++ als Code, Teil 3: Container, die sagen, welche Anforderungen sie erfüllen
Ein Image weiß, woraus es besteht. Das steht in der SBOM. Welche Anforderungen die Pipeline beim Bauen erfüllt hat, stand bisher nirgends am Image. Jetzt hängt an jedem Image eine signierte OSCAL-Komponentendefinition. Sie nennt die Anforderungen aus Grundschutz++, für die es bei genau diesem Build einen Beleg gibt.
Teil 3 der Serie „Grundschutz++ als Code“. Die Übersicht aller Teile steht weiter unten.
01 — Was eine Komponentendefinition beschreibt
OSCAL kennt neben Katalog und Profil ein drittes Modell: die Komponentendefinition. Sie beschreibt, was ein Produkt, ein Dienst oder ein Verfahren für bestimmte Anforderungen tut. NIST hat sie für Hersteller gedacht. Wer Software liefert, sagt damit maschinenlesbar, welche Anforderungen sie unterstützt.
Eine Komponentendefinition ist keine Aussage über ein laufendes System. Sie sagt, was eine Komponente leistet. Ob eine Anforderung in einer Umgebung erfüllt ist, klärt erst eine Messung. Diese Trennung zieht sich durch die ganze Serie.
02 — Wie das BSI Komponenten beschreibt
Die Stand-der-Technik-Bibliothek enthält selbst sechs Komponentendefinitionen (Stand 28.09.2026, Commit 367d775). Darunter sind Keycloak, eine Passwortrichtlinie, eine Netzarchitektur und Vorschläge zur Lieferkettensicherheit. Ein Blick hinein lohnt sich, bevor man eigene schreibt.
- Verweis per UUID: Die Anforderungen stehen dort nicht mit ihrer Kennung wie BER.1.4. Sie stehen mit der UUID, die der Katalog als alternative Kennung führt. Wer beides lesen will, muss verknüpfen.
- Produkt statt Exemplar: Die Keycloak-Definition beschreibt, was Keycloak grundsätzlich unterstützt. Sie ist ausdrücklich als Entwurf markiert und an keine bestimmte Installation gebunden.
- Gemischte Versionen: Keycloak liegt in OSCAL 1.2.2 vor, die Lieferkettensicherheit noch in 1.1.2. Teil 2 hat gezeigt, warum man deshalb gegen die angegebene Version prüft.
Für ein Image aus einer Pipeline reicht das nicht. Dort zählt nicht, was ein Werkzeug kann, sondern was bei diesem Build passiert ist.
03 — Eine Definition pro Image
Die Pipeline erzeugt die Definition bei jedem Build neu und bindet sie an den Digest des Images. Der Generator component.mjs aus grundschutz-worksheets nimmt dafür eine kleine Quelldatei: Anforderung, Beschreibung in eigenen Worten, Links auf die Belege.
node component.mjs source.json \
--subject registry.example.org/app@sha256:… \
--prop pipeline=https://ci.example.org/p/123 > component.json
node validate.mjs component.json- Beide Kennungen: Jede Anforderung trägt die Grundschutz++-Kennung und die UUID aus dem Katalog. Menschen lesen die Kennung, Werkzeuge verknüpfen über die UUID mit den Komponenten des BSI.
- Gegen den Katalog geprüft: Eine Kennung, die im Katalog auf dem festgelegten Commit fehlt, bricht die Erzeugung ab.
- Gegen das Schema geprüft: Bevor etwas signiert wird, prüft
validate.mjsdie Datei gegen das NIST-Schema 1.2.2.
Im Beispiel sind es vier Anforderungen, die eine Build-Pipeline typischerweise abdeckt: Softwarebestandteile (DEV.4.3), Updates externer Software (DEV.4.5), Schwachstellenscans (DET.5.3) und der Integritätstest (TEST.3.1.3).
04 — Nur beanspruchen, was belegt ist
Die erste Fassung hat die Quelldatei aus den Einstellungen der Pipeline gebaut. SBOM eingeschaltet, also DEV.4.3. Scan als Sperre, also DEV.4.5. Das klingt vernünftig und ist trotzdem falsch. Die Datei sagte, wie die Pipeline eingestellt ist, nicht was mit diesem Image passiert ist. Scheitert der Signaturjob oder fehlt die SBOM, stünde beides trotzdem drin.
Die zweite Fassung prüft erst und beschreibt dann. Ein eigener Schritt läuft nach Signatur und Scan und schaut auf den gepushten Digest:
REF=registry.example.org/app@sha256:…
cosign verify --key cosign.pub "$REF"
cosign verify-attestation --key cosign.pub --type cyclonedx "$REF"
# dazu das Urteil des Schwachstellenscans aus derselben Pipeline- DEV.4.3 Softwarebestandteile: nur mit einer SBOM-Attestation, die sich prüfen lässt.
- DEV.4.5 Updates externer Software: nur mit einem Scan als Sperre und ohne offenen Befund über der Schwelle.
- DET.5.3 Schwachstellenscans: nur mit einem Scan-Urteil für genau diesen Digest.
- TEST.3.1.3 Integritätstest: nur mit einer Signatur, die gegen den öffentlichen Schlüssel besteht.
Jeder Eintrag verlinkt seinen Beleg. Was fehlt, fehlt auch in der Definition, und das Log sagt, warum. Ohne einen einzigen Beleg wird nichts signiert.
Eine Falle gibt es dabei. Eine gemeinsame Pipeline-Komponente weiß nicht, in welcher Stage ein Projekt signiert. Hängt der Prüfschritt an einer festen Stage, kann er vor der Signatur liegen, und GitLab lehnt die ganze Pipeline ab. Er gehört deshalb nach .post, die nach allen anderen Stages läuft.
05 — Signieren, anhängen, von außen prüfen
Die fertige Datei hängt wie die SBOM als Attestation am Digest, signiert mit demselben Schlüssel. Wichtig ist die Arbeitsteilung. Der Schritt, der Code aus dem Netz holt und die Datei baut, hat keinen Zugriff auf den Schlüssel. Der Schritt mit dem Schlüssel signiert nur eine fertige Datei.
Ob alles stimmt, zeigt erst eine Prüfung von außen, unabhängig von der Pipeline, die die Datei erzeugt hat:
cosign verify-attestation --key cosign.pub \
--type github.com/ohartwig/grundschutz-worksheets/predicate/oscal-component-definition/v1 \
"$REF" | jq -r .payload | base64 -d | jq .predicate > component.json
node validate.mjs component.json
Ich lasse diese Prüfung als eigenen Fall in einem Beweis-Repository laufen, bei jedem Tag. Er prüft sechs Dinge:
- Die Attestation besteht mit dem richtigen Schlüssel und scheitert mit einem fremden.
- Sie gehört zu genau dem Digest, der gebaut wurde.
- Der signierte Inhalt ist identisch mit der erzeugten Datei.
- Das Repository scannt absichtlich nicht. Also dürfen DEV.4.5 und DET.5.3 nicht drinstehen, und sie stehen nicht drin.
- Jede Kennung steht im Katalog auf dem festgelegten Commit.
- Ein simulierter Wechsel des Katalogs wird erkannt, dazu gleich mehr.
Der vierte Punkt ist der wichtigste. Eine Prüfung, die nur grüne Fälle kennt, zeigt nicht, dass sie etwas weglassen kann.
06 — Wenn sich der Katalog ändert
Grundschutz++ ist noch im Aufbau. Das BSI wird Anforderungen umbenennen, zusammenlegen oder streichen. Eine Definition, die auf einen alten Stand zeigt, bleibt dann formal gültig und sagt trotzdem das Falsche.
Das Werkzeug recheck.mjs vergleicht die beanspruchten Anforderungen mit einem anderen Stand des Katalogs, über Kennung und UUID zugleich:
node recheck.mjs component.json --commit <neuer Commit der Bibliothek>
node recheck.mjs component.json --catalog geaenderter-katalog.json- unchanged: Kennung und UUID wie bisher.
- renamed: Die UUID gibt es noch, unter einer anderen Kennung.
- uuid-changed: Die Kennung gibt es noch, aber womöglich mit anderer Bedeutung.
- withdrawn: Weder Kennung noch UUID stehen noch im Katalog.
Bei jeder Änderung endet das Werkzeug mit einem Fehlercode. So kann es als geplanter Job gegen den aktuellen Stand der Bibliothek laufen. Am 28.09.2026 war der festgelegte Commit noch der aktuelle, es gab also nichts zu melden. Deshalb prüft der Beweis-Fall einen simulierten Wechsel. Er zieht in einer Kopie des Katalogs eine Anforderung zurück und erwartet genau diese Meldung.
Hier zahlt sich aus, dass jede Anforderung beide Kennungen trägt. Nur mit der UUID lässt sich eine Umbenennung von einer Streichung unterscheiden.
07 — Was die Definition nicht sagt
Eine signierte Komponentendefinition ist ein guter Nachweis. Sie ist aber kein Nachweis für alles.
- Nicht die Konfiguration: Ob das Image als root läuft oder welche Ports es öffnet, steht nicht darin.
- Nicht der Betrieb: Ob das Image, das gerade läuft, dieses ist, klärt erst ein Abgleich mit dem Cluster.
- Keine Konformität: Sie sagt, was bei diesem Build belegt war. Ob ein System die Anforderungen erfüllt, ist eine Bewertung.
Genau das ist das Thema von Teil 4: Messungen, die ihre Ergebnisse selbst als OSCAL schreiben.
08 — Die Serie im Überblick
- Grundschutz++ gegen die eigene Dokumentation: die Methode, der Katalog als Datenmodell, der Abgleich mit IaC und GitOps.
- Die Anwendbarkeit als Datensatz: die Anwendbarkeitserklärung als OSCAL-Profil.
- Container, die sagen, welche Anforderungen sie erfüllen: eine signierte Komponentendefinition an jedem Image, das die Pipeline baut. Dieser Beitrag.
- Messung als Nachweis: nächtliche Prüfungen schreiben ihre Ergebnisse als OSCAL. Dazu die zweite Ebene, die im laufenden System findet, was kein Repository kennt.
- Das ISMS als Build-Produkt: ein Sicherheitsplan, der zusammengebaut statt geschrieben wird, mit einer ehrlichen Bilanz des Aufwands.
Ein Teil erscheint erst, wenn der beschriebene Schritt im Betrieb läuft und gemessen ist. Der Code dazu liegt vorher in grundschutz-worksheets. Die Titel werden hier verlinkt, sobald der jeweilige Beitrag online ist.
Häufige Fragen
Warum nicht die Definitionen des BSI nutzen?+
Sie beschreiben Produkte allgemein, und einige sind noch Entwürfe. Für ein einzelnes Image fehlt der Bezug zum Build. Über die UUID lassen sich beide aber verknüpfen: die BSI-Definition für das Produkt, die eigene für den Build.
Was passiert, wenn das BSI den Katalog ändert?+
Die Definition zeigt auf einen festen Commit und bleibt dort gültig. Vor dem Anheben meldet recheck.mjs, welche Anforderungen umbenannt, neu belegt oder gestrichen wurden. Erst danach wird der neue Stand eingetragen.
Ersetzt die Definition die SBOM?+
Geht das auch ohne cosign?+
Ja. Die Komponentendefinition ist eine normale JSON-Datei und lässt sich auch als Release-Artefakt ablegen. Die Attestation bindet sie nur fälschungssicher an einen Digest. Ohne sie muss man der Ablage vertrauen.
Fazit
Eine Komponentendefinition am Image ist schnell gebaut. Schwer ist nur eines: Sie darf nichts behaupten, was nicht belegt ist. Aus Einstellungen erzeugt, sagt sie, was sein sollte. Aus Belegen erzeugt, sagt sie, was war. Mit der Prüfung von außen und dem Abgleich gegen neue Kataloge bleibt sie auch später richtig.
Weiter mit Teil 4: Messung als Nachweis.
Ich hänge an deine Images, was deine Pipeline wirklich belegt. Signiert und von außen prüfbar.
Belegprüfung nach Signatur und Scan, eine OSCAL-Komponentendefinition pro Image, die Attestation mit deinem Schlüssel und ein Prüffall, der zeigt, dass Fehlendes auch fehlt.
Plattform-Betrieb statt Beratung auf Papier: Auf Wunsch baue ich die nächsten Schritte gleich mit, von den Messungen bis zum Sicherheitsplan.
Über den Autor

Kai Ole Hartwig
Programmiert seit 2002 – autodidaktisch gelernt, 2012 mit KO-Web selbständig gemacht. Über 100 Projekte, Fokus auf Security, Performance, Automatisierung und Qualität. Heute freiberuflich: DevSecOps-Beratung, Schulungen und Softwareentwicklung.
