Betrieb & Sicherheit

Software-Lieferkette absichern: Von der Pipeline bis ins Cluster

Eine Stückliste allein schützt niemanden. Wirksam wird die Kette erst, wenn im Build eine SBOM entsteht, das Artefakt signiert wird und das Cluster unsignierte Images abweist. Diese drei Schritte kosten zusammen weniger Aufwand als die erste Nachtschicht, in der niemand sagen kann, ob eine gemeldete Schwachstelle im eigenen Bestand steckt. Der Cyber Resilience Act verlangt die Stückliste inzwischen ohnehin, und NIS2 fragt Betreiber nach demselben Nachweis.

5 Kapitel mit allen Befehlen
Betriebsingenieur analysiert Kosten- und Monitoring-Dashboards an drei Bildschirmen
Seit 1997 am Markt Präsenz & Live-Online 4,9 aus 503 Google-Bewertungen Auch Inhouse für dein Team
Worum es geht

Niemand weiß genau, was im Image steckt

Ein typisches Anwendungsimage enthält ein Basis-Image, eine Laufzeitumgebung und mehrere hundert transitive Abhängigkeiten, von denen kein Mensch im Haus alle kennt. Solange nichts passiert, fällt das nicht auf. Sobald eine Schwachstelle in einer verbreiteten Bibliothek gemeldet wird, beginnt die Suche von vorn: Jemand greppt Dockerfiles, jemand fragt Teams per Chat, und nach zwei Tagen gibt es eine Antwort mit dem Zusatz, dass man sich nicht ganz sicher sei. Genau diese Unsicherheit ist das eigentliche Problem, nicht die Schwachstelle selbst.

Dazu kommt der Rechtsrahmen. Der Cyber Resilience Act ist seit dem 11. Dezember 2024 in Kraft, die Meldepflichten für aktiv ausgenutzte Schwachstellen greifen ab dem 11. September 2026, die vollen Herstellerpflichten ab dem 11. Dezember 2027. Anhang I verlangt von Herstellern eine Stückliste in einem maschinenlesbaren Format, mindestens für die obersten Abhängigkeiten. NIS2 wiederum verpflichtet Betreiber, die Sicherheit ihrer Lieferkette zu bewerten. Beide Seiten fragen damit dasselbe: Was ist drin, woher kommt es, wer haftet dafür.

Der dritte Punkt ist die Alarmflut. Ein einzelner Scanlauf über ein gewachsenes Image meldet leicht dreihundert Funde, von denen die meisten in Bibliotheken stecken, die im Betrieb nie aufgerufen werden. Wer alle abarbeiten will, kommt nie zum Ende und stumpft ab. Ohne Priorisierung nach tatsächlicher Ausnutzbarkeit und ohne die Möglichkeit, nicht betroffene Funde begründet als erledigt zu markieren, wird aus einem Sicherheitswerkzeug ein Ticketgenerator, den nach drei Monaten niemand mehr ernst nimmt.

Miniatur-Szene: Leitstand mit steigender Kostenanzeige, Münzstapel neben einer Cloud, Lupe über einem Leck

Die Kette vom Commit bis zum laufenden Pod

  1. 01 Commit mit festgelegtem Basis-Image und Digest
  2. 02 Build erzeugt Image, SBOM und Herkunftsnachweis
  3. 03 Cosign signiert das Artefakt schlüssellos
  4. 04 Registry bewahrt Signatur und Attestation mit auf
  5. 05 Admission Control prüft Signatur vor dem Start
  6. 06 VEX und Scans halten die Fundliste bearbeitbar
Was du mitnimmst

Vier Bausteine, die nur zusammen wirken

Einzeln bringt keiner der vier Schritte viel. Erst die Kette aus Erzeugen, Signieren, Prüfen und Priorisieren macht aus Werkzeugen einen belastbaren Herkunftsnachweis.

SBOM im Build erzeugen

Die Stückliste entsteht dort, wo das Artefakt entsteht, nicht später beim Scannen der Registry. Syft und Trivy erzeugen sie in wenigen Sekunden, Buildkit kann sie direkt beim Bauen mitschreiben. Wichtig ist nur, dass sie am Digest hängt und nicht an einem beweglichen Tag, sonst beschreibt sie irgendwann ein anderes Image.

Signieren mit Cosign

Eine Signatur beantwortet die Frage, ob dieses Image aus eurer Pipeline stammt. Mit dem schlüssellosen Verfahren wird das kurzlebige Token des CI-Jobs zum Ausweis, es gibt also keinen privaten Schlüssel, den jemand stehlen könnte. Die Signatur landet neben dem Image in derselben Registry und wandert damit automatisch mit.

Herkunftsnachweis nach SLSA

Über die Signatur hinaus beschreibt eine Provenance-Attestation, welcher Quellstand mit welchem Builder gebaut wurde. Damit lässt sich ein Image bis zum Commit zurückverfolgen. Buildkit erzeugt sie mit einem Schalter, GitHub und GitLab liefern die nötigen Angaben aus dem Job. Für Auditoren ist das der Beleg, den eine reine Stückliste nicht liefert.

Durchsetzung im Cluster

Ohne Prüfung beim Deployment bleibt alles Vorherige Dokumentation. Kyverno oder OPA Gatekeeper hängen sich als Admission Controller in die API und weisen Pods ab, deren Image keine gültige Signatur des erwarteten Ausstellers trägt. Starte im Auditmodus, sammle eine Woche Funde ein und schalte erst danach auf Ablehnen um.

Funde priorisieren statt zählen

Nicht jede gemeldete Schwachstelle ist im eigenen Kontext ausnutzbar. Mit VEX-Aussagen dokumentierst du begründet, dass ein Fund nicht zutrifft, und die Liste bleibt bearbeitbar. Sinnvolle Reihenfolge: bekannt ausgenutzte Schwachstellen zuerst, dann alles mit Netzwerkzugriff ohne Anmeldung, danach der Rest im normalen Wartungsfenster.

Tutorial

Von der ersten Stückliste bis zur Regel, die Pods ablehnt

Eine Stückliste allein schützt niemanden, wirksam wird die Kette erst, wenn das Artefakt signiert ist und das Cluster unsignierte Images abweist. Deshalb entsteht hier zuerst die Stückliste im Build, danach Signatur und Herkunftsnachweis, dann die Durchsetzung im Cluster und zum Schluss der Dauerbetrieb aus priorisierten Funden und Nachweisen, die eine Prüfung übersteht. Die Beispiele nutzen GitLab CI, Cosign und Kyverno, lassen sich aber mit GitHub Actions und Gatekeeper eins zu eins nachbauen.

01

Schritt 1: Die Stückliste im Build erzeugen

Eine SBOM, die nachträglich über eine Registry läuft, beschreibt nur, was der Scanner erkennt. Eine SBOM aus dem Build kennt zusätzlich den Quellstand und die Bauumgebung. Deshalb gehört sie in denselben Job, der das Image erzeugt.

Stückliste erzeugen und ans Digest binden
# Image bauen und den unveraenderlichen Digest merken
DIGEST=$(buildah bud --format docker -t registry.example.de/plattform/app:1.4.2 . \
  && buildah push --digestfile /dev/stdout registry.example.de/plattform/app:1.4.2)

# Variante A: Syft, Ausgabe im SPDX-Format
syft scan registry.example.de/plattform/app@${DIGEST} \
  -o spdx-json=sbom.spdx.json

# Variante B: Trivy, Ausgabe im CycloneDX-Format
trivy image --format cyclonedx \
  --output sbom.cdx.json registry.example.de/plattform/app@${DIGEST}

# Variante C: direkt beim Bauen mit Buildkit
docker buildx build --sbom=true --provenance=mode=max \
  -t registry.example.de/plattform/app:1.4.2 --push .

Beziehe die Stückliste immer auf den Digest, nie auf ein Tag. Tags werden überschrieben, Digests nicht. Eine SBOM, die auf app:latest zeigt, beschreibt nach dem nächsten Build ein anderes Image und ist als Nachweis wertlos.

Welches Format du wählst, ist weniger wichtig, als es konsequent durchzuhalten. SPDX ist als ISO-Norm verbreitet und in Beschaffungsprozessen häufig gefordert, CycloneDX ist im Sicherheitsumfeld näher an den Werkzeugen und trägt VEX-Aussagen direkt mit. Beide lassen sich ineinander überführen. Die technische Richtlinie TR-03183-2 des BSI beschreibt, welche Felder eine Stückliste mindestens enthalten muss, und ist damit die praktikabelste Vorlage für den deutschen Kontext.

02

Schritt 2: Signieren und attestieren mit Cosign

Die Signatur beantwortet die Frage nach der Herkunft. Schlüssellos heißt: Der Job weist sich mit seinem kurzlebigen Token aus, ein kurzlebiges Zertifikat wird ausgestellt und der Vorgang in ein öffentliches Protokoll geschrieben. Es gibt keinen dauerhaften privaten Schlüssel.

Signatur und Stückliste an das Image hängen
export COSIGN_YES=true
IMG=registry.example.de/plattform/app@sha256:9f2c...

# Signatur erzeugen
cosign sign "$IMG"

# Stueckliste als Attestation anhaengen
cosign attest --predicate sbom.cdx.json --type cyclonedx "$IMG"

# Pruefen, mit Bindung an Aussteller und Identitaet
cosign verify \
  --certificate-oidc-issuer https://gitlab.example.de \
  --certificate-identity-regexp '^https://gitlab\.example\.de/plattform/app//\.gitlab-ci\.yml@refs/heads/main$' \
  "$IMG"

Die Prüfung bindet zwei Dinge: den Aussteller des Tokens und die Identität des Jobs. Bei GitLab ist das der Pfad der Pipeline-Datei samt Ref, bei GitHub der Pfad des Workflows im Repository.

.gitlab-ci.yml, Job mit Signatur
sign:
  stage: release
  image: gcr.io/projectsigstore/cosign:v2.4.1
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  script:
    - cosign sign --yes "$IMAGE_DIGEST"
    - cosign attest --yes --predicate sbom.cdx.json --type cyclonedx "$IMAGE_DIGEST"
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Der Block id_tokens ersetzt jeden hinterlegten Schlüssel. Wie du dieselbe Föderation für den Zugriff auf AWS und Azure nutzt, steht unter GitLab CI oder GitHub Actions.

03

Schritt 3: Im Cluster durchsetzen statt nur dokumentieren

Bis hierher ist alles freiwillig. Verbindlich wird es erst, wenn die Kubernetes-API einen Pod ablehnt, dessen Image die Prüfung nicht besteht. Dafür setzt sich ein Admission Controller vor jede Erzeugung von Ressourcen.

Kyverno-Regel: nur signierte Images aus der eigenen Registry
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: nur-signierte-images
spec:
  validationFailureAction: Audit
  webhookTimeoutSeconds: 30
  rules:
    - name: signatur-pruefen
      match:
        any:
          - resources:
              kinds: [Pod]
              namespaces: [produktion]
      verifyImages:
        - imageReferences:
            - "registry.example.de/plattform/*"
          mutateDigest: true
          required: true
          attestors:
            - entries:
                - keyless:
                    issuer: "https://gitlab.example.de"
                    subject: "https://gitlab.example.de/plattform/app//.gitlab-ci.yml@refs/heads/main"

mutateDigest: true ersetzt das Tag im Manifest durch den geprüften Digest, sodass später kein anderes Image unter demselben Tag startet. Ab Kyverno 1.13 wandert die Einstellung für das Fehlverhalten in die Regel, prüfe die Schreibweise gegen deine Version.

Was die verbreiteten Werkzeuge leisten

WerkzeugStärkeGrenze
KyvernoRegeln in YAML, Signaturprüfung eingebaut, kann Manifeste zugleich anpassenEigene Sprache, komplexe Bedingungen werden schnell unübersichtlich
OPA GatekeeperSehr ausdrucksstark über Rego, verbreitet in großen UmgebungenRego muss gelernt werden, Signaturprüfung braucht einen zusätzlichen Baustein
Sigstore Policy ControllerAuf Signatur und Attestation zugeschnitten, eng am WerkzeugDeckt nur diesen Zweck ab, allgemeine Regeln brauchen ein zweites Werkzeug
04

Schritt 4: Aus dreihundert Funden die zehn wichtigen ziehen

Die Kette steht, jetzt kommt die Dauerarbeit. Entscheidend ist nicht, wie viele Funde ein Scanner meldet, sondern wie schnell ihr die wirklich gefährlichen erkennt und wie ihr den Rest begründet zur Seite legt.

Scannen, filtern, Ausnahmen begründen
# Nur schwere Funde, und nur solche mit verfuegbarer Korrektur
trivy image --severity HIGH,CRITICAL --ignore-unfixed \
  registry.example.de/plattform/app@sha256:9f2c...

# Bekannte Ausnahmen mit Begruendung und Frist
cat > .trivyignore <<'EOF'
# CVE-2024-XXXXX: betrifft nur den Windows-Pfad, hier nicht erreichbar
# geprueft am 2026-07-20, naechste Pruefung 2026-10-20
CVE-2024-XXXXX
EOF

# VEX-Aussage mitliefern, statt Funde stillschweigend zu unterdruecken
trivy image --vex openvex.json \
  registry.example.de/plattform/app@sha256:9f2c...

Der Unterschied zwischen .trivyignore und einer VEX-Datei ist die Nachvollziehbarkeit. Die Ignorierliste gilt lokal für ein Werkzeug, VEX ist eine dokumentierte Aussage über Betroffenheit, die auch Kunden und Auditoren lesen können.

Die Reihenfolge, in der abgearbeitet wird

  • Zuerst alles, was nachweislich aktiv ausgenutzt wirdBekannt ausgenutzte Schwachstellen sind der einzige Fundtyp, bei dem der Angriff bereits existiert. Alles andere ist Wahrscheinlichkeit, dieser Teil ist Gegenwart.
  • Danach alles, was ohne Anmeldung über das Netz erreichbar istEin Fund in einer Bibliothek, die nur ein interner Batchlauf berührt, hat ein völlig anderes Risiko als einer im öffentlich erreichbaren Eingang. Ohne diese Unterscheidung arbeitest du nach Zufall.
  • Basis-Images wöchentlich neu bauen statt einzeln zu flickenEin Großteil der Funde verschwindet allein durch ein aktuelles Basis-Image. Ein fester Neubau-Termin erledigt mehr Meldungen als jede manuelle Nachbesserung.
  • Jede Ausnahme mit Begründung und Ablaufdatum versehenAusnahmen ohne Frist bleiben für immer stehen. Mit Ablaufdatum taucht der Fund von selbst wieder auf und wird erneut bewertet, statt still im Bestand zu verschwinden.
  • Den Bestand regelmäßig gegen die eigene SBOM abfragenWenn eine neue Schwachstelle gemeldet wird, muss die Antwort auf die Frage nach Betroffenheit Minuten dauern und nicht Tage. Genau dafür wurde die Stückliste erzeugt.

Halte alle Stücklisten an einem Ort vor, entweder in einer Registry als Attestation oder in einem eigenen Verzeichnisdienst. Erst dann lässt sich die Frage nach einer betroffenen Bibliothek über alle Anwendungen hinweg beantworten. In Umgebungen ohne Internetzugang ist dieser Bestand ohnehin Pflicht, weil kein Scanner nebenbei nachladen kann. Wie das ohne Netzanbindung aussieht, beschreibt Kubernetes air-gapped betreiben.

05

Schritt 5: Nachweise, die eine Prüfung überstehen

Wer Produkte mit digitalen Elementen verkauft, ist Hersteller im Sinne des Cyber Resilience Act. Wer nur betreibt, fällt unter die Lieferkettenpflichten aus NIS2. Beide Rollen brauchen dieselben Belege, nur mit unterschiedlicher Adressierung.

Was in der Nachweismappe liegen sollte

  • Je Release eine Stückliste in einem maschinenlesbaren Format, verknüpft mit dem Digest
  • Herkunftsnachweis mit Quellstand, Bauzeitpunkt und Kennung der Bauumgebung
  • Die geltende Cluster-Regel samt Datum der Umstellung von Mitschreiben auf Ablehnen
  • Verfahren für Schwachstellenmeldungen mit benannter Zuständigkeit und Reaktionsfrist
  • Liste der Ausnahmen mit Begründung, Prüfdatum und Ablaufdatum
Stückliste aus der Registry zurückholen
# Attestation zum Image herunterladen und lesbar machen
cosign download attestation \
  registry.example.de/plattform/app@sha256:9f2c... \
  | jq -r '.payload' | base64 -d | jq '.predicate' > sbom-aus-registry.json

# Bestand durchsuchen: welche Anwendung enthaelt die betroffene Bibliothek
jq -r '.components[] | select(.name=="libxml2") | [.name,.version] | @tsv' \
  sboms/*.cdx.json

Genau diese zweite Abfrage ist der Punkt, an dem sich der ganze Aufwand rechnet. Sie beantwortet in Sekunden, was sonst Tage an Rückfragen kostet.

Denk daran, dass Nachweise auch gegenüber euren eigenen Lieferanten gelten. Fordere bei eingekaufter Software eine Stückliste und einen benannten Ansprechpartner für Schwachstellen ein, am besten vertraglich. Für Betreiber kritischer Dienste ist das kein zusätzlicher Wunsch, sondern Teil der Pflichten, die NIS2 für Cloud-Dienstleister beschreibt. Wer erst beim Vorfall nachfragt, verhandelt zum denkbar schlechtesten Zeitpunkt.

Gut zu wissen

Häufige Fragen zu Lieferkettensicherheit

Noch etwas offen? Wir sind ohne Warteschleife für dich da.

Frag uns direkt
Reicht eine SBOM, um den Cyber Resilience Act zu erfüllen?
Nein, sie ist nur ein Teil. Anhang I verlangt von Herstellern eine maschinenlesbare Stückliste, mindestens für die obersten Abhängigkeiten, daneben aber auch ein Verfahren für den Umgang mit Schwachstellen, Sicherheitsaktualisierungen über den Unterstützungszeitraum und Meldungen an die zuständigen Stellen. Die Meldepflichten für aktiv ausgenutzte Schwachstellen greifen ab dem 11. September 2026, die vollen Pflichten ab dem 11. Dezember 2027. Die Stückliste ist der einfachste Baustein und deshalb ein guter Anfang, aber eben nur der Anfang.
SPDX oder CycloneDX, welches Format sollen wir nehmen?
Nimm das Format, das eure Abnehmer verlangen, und halte es durch. SPDX ist als ISO-Norm etabliert und taucht häufiger in Ausschreibungen und Beschaffungsvorgaben auf. CycloneDX kommt aus dem Sicherheitsumfeld, ist enger mit den Scannern verzahnt und trägt VEX-Aussagen direkt mit. Beide Formate lassen sich ineinander überführen, der Aufwand dafür ist gering. Wichtiger als die Wahl ist, dass jede Stückliste an einem Digest hängt und dass sie automatisch im Build entsteht statt von Hand.
Brauchen wir eigene Schlüssel oder reicht schlüsselloses Signieren?
Für den Regelfall reicht schlüssellos, und es ist meistens sicherer. Ein dauerhafter privater Schlüssel muss aufbewahrt, gedreht und im Notfall gesperrt werden, und genau daran scheitern die meisten Aufbauten. Beim schlüssellosen Verfahren weist sich der Job über sein kurzlebiges Token aus, das Zertifikat lebt wenige Minuten. Eigene Schlüssel in einem Hardware-Modul lohnen dort, wo eine Aufsicht sie ausdrücklich verlangt oder wo ohne Internetzugang gearbeitet wird und die öffentlichen Dienste nicht erreichbar sind.
Wie gehen wir mit hunderten Meldungen aus dem Scanner um?
Mit einer festen Reihenfolge statt mit Vollständigkeit. Zuerst kommt alles, was nachweislich aktiv ausgenutzt wird, danach alles, was ohne Anmeldung über das Netz erreichbar ist, danach der Rest im normalen Wartungsfenster. Ein wöchentlicher Neubau mit aktuellem Basis-Image erledigt einen Großteil der Funde ohne Einzelbearbeitung. Alles, was übrig bleibt und nicht zutrifft, bekommt eine VEX-Aussage mit Begründung und Ablaufdatum. Ohne Ablaufdatum werden aus Ausnahmen dauerhafte blinde Flecken.
Bremst die Admission Control unsere Deployments aus?
Spürbar nur, wenn sie falsch konfiguriert ist. Die Prüfung selbst dauert Millisekunden, weil Signatur und Attestation neben dem Image in derselben Registry liegen. Kritisch sind zwei Punkte: Ein zu knapper Zeitwert für den Webhook lässt Deployments bei langsamer Registry scheitern, und ein Controller ohne Hochverfügbarkeit wird selbst zum Ausfallpunkt für die gesamte API. Betreibe ihn mit mehreren Repliken, setze den Zeitwert bewusst und prüfe im Auditmodus, bevor du auf Ablehnen umstellst.

Zuletzt geprüft am 26. Juli 2026.

Das sagen Teilnehmer

Echte Stimmen aus unseren IT-Kursen

Der Kursinhalt entsprach voll meinen Erwartungen, die richtige Mischung aus Theorie und Praxis.
Rückmeldung aus dem Kurs „Kubernetes Grundkurs“
Super, komplett auf uns und unsere Bedürfnisse eingegangen. Der Tag hat uns viel geholfen und wir könnten das alles in unserem Arbeitsalltag nutzen.
Rückmeldung aus dem Kurs „DP-080 Training: Abfragen von Daten mit Microsoft Transact-SQL (DP-080T00)“
Persönlich für dich da

Deine Ansprechpartner

Du bist dir nicht sicher, welcher Kurs oder welches Level zu dir passt? Wir beraten dich persönlich und kostenlos.

Yves Hoppe

Yves Hoppe

Weiterbildung & Beratung

Hilft dir, aus dem Cloud-Programm den passenden Kurs oder Lernpfad zu finden.

Norbert Jansen

Norbert Jansen

Beratung & Inhouse

Plant mit dir Inhouse-Trainings, die exakt auf eure Systemlandschaft und Distributionen zugeschnitten sind.

Nächster Schritt

Die Kette bauen, statt sie zu dokumentieren

Die Bausteine verteilen sich auf zwei Welten, und genauso sind unsere Kurse geschnitten: Continuous Integration und Delivery mit GitLab für Build und Signatur, der Kubernetes Grundkurs und die Helm-Schulung für die Durchsetzung im Cluster, der Linux Container Workshop für schlanke und nachvollziehbare Images. Wenn du nicht sicher bist, wo dein Team anfangen sollte, sprich uns an, wir sehen uns eure Pipeline gemeinsam an.