Container Supply Chain absichern: Praxisleitfaden zu Sigstore, Cosign und Policy Enforcement
Angriffe auf die Container Supply Chain gehören zu den kritischsten Bedrohungsvektoren in der modernen Softwareentwicklung. Wenn es einem Angreifer gelingt, ein Container Image zu kompromittieren — sei es durch bösartige Einschleusung während des Build-Prozesses, durch Manipulation der Registry oder durch Dependency Poisoning — können sich die Folgen kaskadierend über eine gesamte Infrastruktur ausbreiten. Wer Container ohne Verifizierungsmechanismen deployt, arbeitet mit der impliziten Annahme, dass Images authentisch und unverändert sind. Diese Annahme hat sich angesichts der Supply-Chain-Vorfälle der letzten Jahre als gefährlich optimistisch erwiesen.
Das kryptografische Signieren von Container Images adressiert genau die Dimensionen Authentizität und Integrität. Ein signiertes Image liefert einen überprüfbaren Herkunftsnachweis und garantiert, dass sein Inhalt seit dem Signieren nicht verändert wurde. Software Bills of Materials (SBOMs) ergänzen dies um Transparenz über den Abhängigkeitsbaum eines Images — und erlauben damit eine schnelle Identifikation von Schwachstellen sowie eine belastbare Compliance-Prüfung. Zusammen verwandeln diese Mechanismen ein Container-Deployment von einem vertrauensbasierten Vorgang in einen verifizierbaren, auditierbaren Prozess.
Dieser Leitfaden zeigt eine vollständige, praxistaugliche Implementierung von Container Supply Chain Security mit dem Sigstore-Ökosystem. Am Ende verfügen Sie über einen funktionsfähigen GitHub-Actions-Workflow, der Container Images baut, signiert und mit SBOMs attestiert, sowie über ein Policy-Enforcement-System in Kubernetes, das diese Signaturen vor jedem Deployment validiert.
Alle in diesem Leitfaden referenzierten Beispielkonfigurationen, Kubernetes-Manifeste und Policy-Definitionen finden Sie im begleitenden Repository unter https://github.com/think-ahead-technologies/blog-container-signing.
Voraussetzungen
Bevor Sie mit der Umsetzung beginnen, stellen Sie sicher, dass Sie folgende Grundlagen bereitstellen:
- Aktives GitHub-Konto
- Zugriff auf einen Kubernetes-Cluster, in dem Sie Admission Controller installieren und Workloads deployen können (lokale Cluster wie kind oder minikube eignen sich für Tests)
- Ein Container Image zum Signieren — dieser Leitfaden verwendet nginx als Beispielanwendung; Sie können jedoch jede containerisierte Anwendung mit einem gültigen Dockerfile einsetzen
Die Komponenten im Überblick
Sigstore ist ein Open-Source-Projekt, das ein umfassendes Framework für das Signieren, Verifizieren und Schützen von Software-Artefakten bereitstellt. Statt Entwicklerinnen und Entwickler mit der Verwaltung langlebiger kryptografischer Schlüssel zu belasten — ein Vorgang mit erheblichen sicherheits- und betriebstechnischen Fallstricken — setzt Sigstore auf kurzlebige Zertifikate, die an OpenID-Connect-Identitäten (OIDC) gebunden sind. Damit entfällt die Schlüsselverwaltung, ohne dass kryptografische Belastbarkeit oder Nachvollziehbarkeit der Artefakt-Herkunft leiden.
Cosign ist das zentrale Werkzeug zum Signieren und Verifizieren von Container Images im Sigstore-Ökosystem. Ab Version 3.0.2 unterstützt Cosign Keyless Signing über die Integration mit Fulcio, der Zertifizierungsstelle von Sigstore. Fulcio stellt kurzlebige Zertifikate aus, die ephemere Schlüssel an OIDC-Identitäten von Anbietern wie GitHub, Google oder Microsoft binden. Beim Signieren eines Images speichert Cosign Signatur und zugehörige Metadaten in der Container Registry neben dem Image ab, während parallel ein unveränderlicher Eintrag im Sigstore-Transparenzlog Rekor entsteht. Diese zweigleisige Ablage sorgt dafür, dass Signaturen auch nach Ablauf des Signaturzertifikats verifizierbar bleiben.
Syft, entwickelt von Anchore, erzeugt SBOMs, indem es Container Images und Dateisysteme analysiert und alle Softwarekomponenten sowie Abhängigkeiten katalogisiert. Version 1.36.0 unterstützt mehrere SBOM-Formate, darunter SPDX und CycloneDX — die beiden Industriestandards zur Beschreibung von Softwarezusammensetzungen. SPDX, ursprünglich von der Linux Foundation entwickelt, spielt seine Stärken bei Lizenz-Compliance aus und ist in Unternehmensumgebungen weit verbreitet. CycloneDX wird von OWASP gepflegt und ist speziell für Security-Anwendungsfälle konzipiert; es bietet umfassende Möglichkeiten zur Schwachstellenverfolgung.
Policy Controller ist ein Kubernetes-Admission-Controller, der die Verifizierung von Image-Signaturen als Policy zur Deployment-Zeit erzwingt. Als Validating Webhook fängt Policy Controller Pod-Erstellungsanfragen ab und bewertet sie gegen ClusterImagePolicy-Ressourcen. Mit Version 0.13.0 kam die Unterstützung für das Sigstore-Bundle-Format hinzu, das die Serialisierung und Speicherung von Signaturen und Attestierungen standardisiert. Bevor ein Container gestartet wird, verifiziert Policy Controller die Image-Signatur gegen das Rekor-Transparenzlog und prüft angehängte Attestierungen wie SBOMs. Diese Enforcement-Schicht stellt sicher, dass in Ihrem Cluster ausschließlich verifizierte, konforme Images laufen.
GitHub-Actions-Workflow — Schritt für Schritt
Dieser Abschnitt beleuchtet jeden einzelnen Baustein des Signing- und Attestierungs-Workflows. Der vollständige, integrierte Workflow folgt im nächsten Abschnitt.
3.1 Aufbau der Workflow-Datei
Die Workflow-Datei (.github/workflows/build-sign-sbom.yaml) beginnt mit der Trigger-Konfiguration und den entscheidenden Berechtigungseinstellungen:
name: Build, Sign, and Attest Container Image
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read # Read repository contents
packages: write # Push to GitHub Container Registry
id-token: write # Required for OIDC authentication with Sigstore
Die Berechtigung id-token: write ist für Keyless Signing zwingend erforderlich. Sie erlaubt dem Workflow, ein OIDC-Token vom Identity Provider von GitHub anzufordern, mit dem Fulcio anschließend ein kurzlebiges Signaturzertifikat ausstellt. Ohne diese Berechtigung schlägt Keyless Signing fehl. Das Token enthält Claims zur Identität des Workflows (Repository, Commit-SHA, Workflow-Name) und wird Teil der signierten Metadaten.
3.2 Container Image bauen
Der Build-Schritt nutzt Docker Buildx für Multi-Platform-Support und taggt das Image für die GitHub Container Registry:
- name: Build container image
run: |
docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
docker tag ghcr.io/${{ github.repository }}:${{ github.sha }} \
ghcr.io/${{ github.repository }}:latest
Die Verwendung des Commit-SHA als primärer Tag schafft eine unveränderliche Referenz auf das Image, während der latest-Tag den Komfort für Entwicklungs-Workflows liefert.
3.3 Push in die GitHub Container Registry
Nach dem Build werden beide Tags in die Registry gepusht:
- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push container image
run: |
docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
docker push ghcr.io/${{ github.repository }}:latest
Das Image muss vor dem Signieren in der Registry vorliegen, denn Cosign referenziert es über den Digest — nicht über den Tag. Damit bleibt die Signatur unabhängig von Tag-Mutationen gültig.
3.4 Cosign und Syft installieren
Fixieren Sie konkrete Werkzeug-Versionen, um reproduzierbare Builds zu ermöglichen und unerwartete Verhaltensänderungen durch Versionssprünge zu vermeiden:
- name: Install Cosign
uses: sigstore/cosign-installer@v4.0.0
with:
cosign-release: "v2.6.1"
- name: Install Syft
run: |
curl -sSfL https://get.anchore.io/syft | sh -s -- -b /usr/local/bin v1.36.0
Version Pinning schützt Ihre Pipeline vor Breaking Changes. Aktualisieren Sie Versionen bewusst — und erst nach einem Test in einer Nicht-Produktivumgebung.
3.5 SBOMs generieren
Generieren Sie SBOMs in den Formaten SPDX und CycloneDX, um maximale Kompatibilität zu erreichen:
# Generate SPDX format SBOM (Linux Foundation standard, license compliance focus)
- name: Generate SPDX SBOM
env:
DIGEST: ${{ steps.image-digest.outputs.digest }}
run: |
syft scan ghcr.io/${{ github.repository }}@${DIGEST} \
-o spdx-json=sbom-spdx.json
echo "SPDX SBOM generated successfully"
# Generate CycloneDX format SBOM (OWASP standard, security focus)
- name: Generate CycloneDX SBOM
env:
DIGEST: ${{ steps.image-digest.outputs.digest }}
run: |
syft scan ghcr.io/${{ github.repository }}@${DIGEST} \
-o cyclonedx-json=sbom-cyclonedx.json
echo "CycloneDX SBOM generated successfully"
3.6 Image-Digest ermitteln
Vor dem Signieren wird der unveränderliche Digest des gepushten Images ermittelt. Digests sind kryptografische Hashes, die den Inhalt eines Images eindeutig identifizieren — im Gegensatz zu Tags, die neu vergeben werden können:
- name: Get image digest
id: image-digest
run: |
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' \
ghcr.io/${{ github.repository }}:${{ github.sha }} | cut -d'@' -f2)
echo "digest=${DIGEST}" >> $GITHUB_OUTPUT
echo "Image digest: ${DIGEST}"
Der Digest wird als Workflow-Output (steps.image-digest.outputs.digest) hinterlegt und in den folgenden Signing- und Attestierungs-Schritten wiederverwendet. Signieren über den Digest — statt über den Tag — sorgt dafür, dass die Signatur kryptografisch fest an einen konkreten Image-Inhalt gebunden bleibt, unabhängig von Tag-Änderungen.
3.7 Container Image signieren
Signieren Sie das Image per Keyless-Authentifizierung über den OIDC-Provider von GitHub:
- name: Sign container image
env:
DIGEST: ${{ steps.image-digest.outputs.digest }}
run: |
cosign sign --yes \
ghcr.io/${{ github.repository }}@${DIGEST}
Das Flag --yes überspringt die interaktive Bestätigungsabfrage — in CI/CD-Umgebungen unverzichtbar. Cosign erkennt das GitHub-OIDC-Token automatisch über die Berechtigung id-token: write und authentifiziert sich damit bei Fulcio. Fulcio stellt ein kurzlebiges Zertifikat aus (mit einer Gültigkeit von rund zehn Minuten), das den ephemeren Signaturschlüssel an die Identität des Workflows bindet. Die Signatur wird als separates Artefakt neben dem Image-Digest in der Registry abgelegt, ein unveränderlicher Eintrag entsteht parallel im Rekor-Transparenzlog.
Beim Signieren eines Images hält Cosign drei kritische Metadaten fest:
- Die Signatur selbst — kryptografischer Nachweis, dass die Entität hinter der OIDC-Identität dieses Image freigegeben hat
- Das Zertifikat — enthält die OIDC-Identity-Claims (Repository, Workflow, Commit-SHA, Actor)
- Den Rekor-Eintrag — unveränderlicher, mit Zeitstempel versehener Beleg, dass die Signatur erfolgt ist
Diese Metadaten ermöglichen es, nicht nur zu verifizieren, dass ein Image signiert wurde, sondern auch von wem und wann.
3.8 SBOM-Attestierungen signieren und anhängen
Hängen Sie beide SBOMs als signierte Attestierungen an das Container Image:
- name: Attest SPDX SBOM
env:
DIGEST: ${{ steps.image-digest.outputs.digest }}
run: |
cosign attest --yes \
--type spdxjson \
--predicate sbom-spdx.json \
ghcr.io/${{ github.repository }}@${DIGEST}
- name: Attest CycloneDX SBOM
env:
DIGEST: ${{ steps.image-digest.outputs.digest }}
run: |
cosign attest --yes \
--type cyclonedx \
--predicate sbom-cyclonedx.json \
ghcr.io/${{ github.repository }}@${DIGEST}
Attestierungen unterscheiden sich grundlegend von einer einfachen Signaturprüfung. Während eine Signatur belegt, wer ein Artefakt erzeugt hat, belegen Attestierungen Eigenschaften eines Artefakts. Eine SBOM-Attestierung bindet die SBOM kryptografisch an das Image und beweist, dass genau diese SBOM den Inhalt genau dieses Images korrekt abbildet. Diese Bindung verhindert, dass Angreifer eine harmlose SBOM einem kompromittierten Image unterschieben — oder umgekehrt.
Attestierungen nutzen das in-toto-Format, den Industriestandard für Supply-Chain-Metadaten. Das Flag --predicate bestimmt den Attestierungsinhalt (die SBOM), --type gibt den Attestierungstyp für die Policy-Auswertung an. Policy Controller kann später bestimmte Attestierungstypen einfordern und damit sicherstellen, dass Images nicht nur SBOMs mitbringen, sondern SBOMs im erwarteten Format.
Vollständiges Beispiel eines GitHub-Actions-Workflows
Das vollständige Beispiel finden Sie im Companion Repository.
Dieser Workflow erzeugt ein vollständig signiertes und attestiertes Container Image mit:
- Kryptografischer Signatur, die belegt, dass das Image im Workflow dieses Repositories entstanden ist
- SPDX-SBOM-Attestierung für Lizenz-Compliance und allgemeine Supply-Chain-Dokumentation
- CycloneDX-SBOM-Attestierung für Schwachstellenmanagement und Security-Analyse
- Rekor-Transparenzlog-Einträgen als unveränderliche Audit-Trails für alle Signaturen und Attestierungen
Sämtliche Artefakte liegen in der GitHub Container Registry und sind über den Digest an das Image gebunden — sie bleiben der jeweiligen Image-Version zugeordnet, unabhängig von späteren Tag-Änderungen.
Deployment nach Kubernetes
Ist die Signing- und Attestierungs-Pipeline betriebsbereit, folgt im nächsten Schritt das Deployment des signierten Container Image nach Kubernetes — inklusive Policy-basierter Durchsetzung. Bevor Policy Controller aktiviert wird, empfiehlt sich ein einfacher Basis-Workload, um die Grundfunktionalität herzustellen und zu verifizieren, dass signierte Images korrekt laufen. Dieser Abschnitt zeigt das Deployment am Beispiel von nginx; die Muster gelten analog für jeden containerisierten Workload.
Legen Sie zunächst einen Namespace für die Anwendung an:
apiVersion: v1
kind: Namespace
metadata:
name: signed-apps
labels:
policy.sigstore.dev/include: "true"
Deployen Sie das signierte Container Image:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
namespace: signed-apps
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f
Wenden Sie die Manifeste auf den Cluster an:
kubectl apply -f nginx-deployment.yaml
Prüfen Sie den Deployment-Status:
kubectl get pods -n signed-apps
kubectl logs -n signed-apps -l app=nginx
Zu diesem Zeitpunkt läuft das Deployment unabhängig vom Signaturstatus durch, da noch keine Policy aktiv ist. Im nächsten Abschnitt richten wir Policy Controller ein, damit Signaturen vor dem Pod-Start validiert werden.
Die vollständigen Kubernetes-Manifeste inklusive Policy-Konfigurationen für die stufenweise Einführung finden Sie im begleitenden Repository unter https://github.com/think-ahead-technologies/blog-container-signing im Verzeichnis kubernetes/.
Sigstore Policy Controller installieren und konfigurieren
Die Durchsetzung durch Policy Controller sollten Sie schrittweise einführen — beginnend mit Beobachtbarkeit, bis Sie in die blockierende Durchsetzung übergehen. So minimieren Sie Betriebsstörungen und bauen Vertrauen in die Policy-Konfiguration auf.
Policy Controller installieren
Installieren Sie Policy Controller v0.13.0 mit Helm:
# Add the Sigstore Helm repository
helm repo add sigstore https://sigstore.github.io/helm-charts
helm repo update
# Install Policy Controller in the cosign-system namespace
helm upgrade --install \
-create-namespace policy-controller \
-n cosign-system \
sigstore/policy-controller \
--wait
Prüfen Sie die Installation:
kubectl get pods -n cosign-system
ClusterImagePolicy verstehen
ClusterImagePolicy ist eine Custom Resource, die die Anforderungen an die Signaturverifizierung definiert. Jede Policy legt fest:
- Image-Muster — auf welche Images die Policy zutrifft (Glob-Patterns möglich)
- Authorities — vertrauenswürdige Public Keys oder Zertifikatsidentitäten
- Attestierungsanforderungen — geforderte Attestierungstypen (z. B. SBOM, SLSA-Provenance)
- Mode —
enforce(blockierend) oderwarn(nur Audit)
Eine grundlegende Policy-Struktur sieht so aus:
apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: example-policy
spec:
images:
- glob: "**"
authorities:
- keyless:
url: https://fulcio.sigstore.dev
identities:
- issuer: https://token.actions.githubusercontent.com
subject: https://github.com/think-ahead-technologies/blog-container-signing/.github/workflows/*
mode: enforce
Stufe 1 — Warn Mode
Beginnen Sie im Warn Mode, um Policy-Verstöße zu beobachten, ohne Deployments zu blockieren. Diese Stufe zeigt, welche Images bei aktiver Durchsetzung durchfallen würden, und gibt Ihnen Zeit, sie zu bereinigen.
apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
name: cip
spec:
images:
- glob: "**"
authorities:
- keyless:
# Use Sigstore's public Fulcio instance
url: https://fulcio.sigstore.dev
identities:
# Match any GitHub Actions workflow from your organization
- issuer: "https://token.actions.githubusercontent.com"
subjectRegExp: "https://github.com/think-ahead-technologies/blog-container-signing/.github/workflows/build-sign-sbom.yaml@refs/heads/main"
mode: warn
Wenden Sie die Policy auf den Cluster an:
kubectl apply -f kubernetes/policy-warn.yaml
Deployen Sie ein unsigniertes Test-Image, um das Warn-Verhalten zu beobachten:
> kubectl create deploy unsigned-test --image=nginx -n signed-apps
Warning: failed policy: cip: spec.template.spec.containers[0].image
Warning: index.docker.io/library/nginx:latest@sha256:f547e3d0d5d02f7009737b284abc87d808e4252b42dceea361811e9fc606287f attestation keyless validation failed for authority authority-0 for index.docker.io/library/nginx@sha256:f547e3d0d5d02f7009737b284abc87d808e4252b42dceea361811e9fc606287f: no matching attestations:
deployment.apps/nginx created
Das Deployment wird wie erwartet angelegt. Die Meldung weist jedoch aus, dass das Image die Prüfung nicht bestanden hat und nur wegen des Warn Mode zugelassen wurde. Räumen Sie es wieder auf:
kubectl delete deploy unsigned-test -n signed-apps
Stufe 2 — Signaturverifizierung
Nachdem Sie im Warn Mode bestätigt haben, dass Ihre signierten Images die Policy erfüllen, aktivieren Sie die Durchsetzung für die Signaturverifizierung:
apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
name: cip
spec:
images:
- glob: "**"
authorities:
- keyless:
# Use Sigstore's public Fulcio instance
url: https://fulcio.sigstore.dev
identities:
# Match any GitHub Actions workflow from your organization
- issuer: "https://token.actions.githubusercontent.com"
subject: "https://github.com/think-ahead-technologies/blog-container-signing/.github/workflows/build-sign-sbom.yaml@refs/heads/main"
mode: enforce
Wenden Sie die aktualisierte Policy an:
kubectl apply -f kubernetes/cip-enforce.yaml
Testen Sie mit Ihrem signierten nginx-Image:
# This should succeed (image is signed)
kubectl run signed-nginx \
--image=ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f \
-n signed-apps
Testen Sie mit einem unsignierten Image:
# This should be blocked
kubectl run unsigned-test --image=nginx:latest -n signed-apps
Das Deployment des unsignierten Images schlägt mit einer Fehlermeldung zur Signaturverifizierung fehl:
Error from server (BadRequest): admission webhook "policy.sigstore.dev" denied the request:
validation failed: failed policy: github-signed-images-enforce:
spec.containers[0].image: ghcr.io/nginx:latest signature key validation failed
Dieser Fehler bestätigt, dass Policy Controller die Signaturanforderungen tatsächlich durchsetzt.
SBOM-Attestierungen verifizieren
Erweitern Sie die Policy so, dass zusätzlich zur Signatur auch SBOM-Attestierungen gefordert werden. Damit stellen Sie sicher, dass Images nicht nur signiert sind, sondern auch die für Compliance und Security-Analyse notwendige Supply-Chain-Transparenz mitbringen.
apiVersion: policy.sigstore.dev/v1alpha1
kind: ClusterImagePolicy
metadata:
name: cip
spec:
images:
- glob: "**"
authorities:
- keyless:
# Use Sigstore's public Fulcio instance
url: https://fulcio.sigstore.dev
identities:
# Match any GitHub Actions workflow from your organization
- issuer: "https://token.actions.githubusercontent.com"
subject: "https://github.com/think-ahead-technologies/blog-container-signing/.github/workflows/build-sign-sbom.yaml@refs/heads/main"
attestations:
- name: spdx-sbom-required
predicateType: https://spdx.dev/Document
policy:
type: cue
data: |
predicateType: "https://spdx.dev/Document"
- name: cyclonedx-sbom-required
predicateType: https://cyclonedx.org/bom
policy:
type: cue
data: |
predicateType: "https://cyclonedx.org/bom"
mode: enforce
Wenden Sie die umfassende Policy an:
kubectl apply -f policy-complete.yaml
Testen Sie das Deployment eines Images mit Signatur und Attestierungen:
# Should succeed (has signature + SBOMs)
kubectl run fully-attested-nginx \
--image=ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f \
-n signed-apps
Verifizierung und Tests
Manuelle Verifizierung schafft Vertrauen in die Signing- und Attestierungs-Pipeline, bevor Sie mit der Enforcement-Policy in den Produktivbetrieb gehen.
Image-Signaturen verifizieren
Verwenden Sie Cosign zur manuellen Verifizierung einer Image-Signatur:
# Verify with GitHub OIDC identity
cosign verify \
--certificate-identity-regexp="^https://github.com/think-ahead-technologies/blog-container-signing" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f
Zu erwartende Ausgabe bei gültiger Signatur:
Verification for ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f
The following checks were performed on each of these signatures:
- The cosign claims were validated
- Existence of the claims in the transparency log was verified offline
- The code-signing certificate was verified using trusted certificate authority certificates
[{"critical": {"identity": {"docker-reference": "ghcr.io/think-ahead-technologies/blog-container-signing"}...}]
Die Ausgabe bestätigt drei zentrale Prüfungen:
- Die Signatur wird kryptografisch gegen den Image-Digest verifiziert
- Die Signatur existiert im Rekor-Transparenzlog
- Das Signaturzertifikat lässt sich auf eine vertrauenswürdige Root (Fulcio) zurückführen
SBOM-Attestierungen inspizieren
Lesen Sie die an das Image angehängten SBOM-Attestierungen aus:
# Download SPDX SBOM attestation
cosign verify-attestation \
--type spdxjson \
--certificate-identity-regexp="^https://github.com/think-ahead-technologies/blog-container-signing" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f | jq -r '.payload' | base64 -d | jq .
Der Befehl dekodiert die Attestierung und zeigt den SPDX-SBOM-Inhalt an. Sie können Paketlisten, Abhängigkeitsbeziehungen und Lizenzinformationen einsehen.
Erwartete Ausgabestruktur der SPDX-SBOM:
{
"predicateType": "https://spdx.dev/Document",
"predicate": {
"spdxVersion": "SPDX-2.3",
"name": "ghcr.io/think-ahead-technologies/blog-container-signing",
"packages": [
{
"name": "nginx",
"versionInfo": "1.25.3",
"supplier": "Organization: nginx",
"filesAnalyzed": false
},
...
]
}
}
# Download CycloneDX SBOM attestation
cosign verify-attestation \
--type cyclonedx \
--certificate-identity-regexp="^https://github.com/think-ahead-technologies/blog-container-signing" \
--certificate-oidc-issuer="https://token.actions.githubusercontent.com" \
ghcr.io/think-ahead-technologies/blog-container-signing:c833b6902c4f5f10be28c107b2bcf01d6c108c5f | jq -r '.payload' | base64 -d | jq .
Erwartete Ausgabestruktur der CycloneDX-SBOM:
{
"predicateType": "https://cyclonedx.org/bom",
"predicate": {
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"components": [
{
"type": "library",
"name": "openssl",
"version": "3.0.2",
"purl": "pkg:deb/debian/openssl@3.0.2"
},
...
]
}
}
Die CycloneDX-Ausgabe listet Komponenten inklusive Schwachstellenkennungen (sofern verfügbar) auf — die Grundlage für die Anbindung an ein Schwachstellenmanagement.
Häufige Probleme und Lösungen
Bei der Umsetzung dieses Workflows begegnen Ihnen typischerweise folgende Stolperstellen:
1. Fehler „Failed to get OIDC token” beim Signieren
- Ursache: Die Berechtigung
id-token: writefehlt oder ist falsch gesetzt - Lösung: Prüfen Sie, dass
permissions.id-token: writeauf Workflow-Ebene gesetzt ist — nicht ausschließlich auf Job-Ebene. GitHub-OIDC-Token erfordern eine explizite Berechtigung.
2. Fehler „Registry authentication failed” beim Push
- Ursache:
GITHUB_TOKENbesitzt keine Schreibrechte für die GitHub Container Registry - Lösung: Setzen Sie
permissions.packages: writeund stellen Sie sicher, dass die GitHub Container Registry für das Repository aktiviert ist. Bei Organisations-Repositories muss zusätzlich die Package-Erstellung erlaubt sein.
3. Policy Controller blockiert Systempods nach Aktivierung der Durchsetzung
- Ursache: ClusterImagePolicy greift standardmäßig für alle Namespaces — auch für Infrastruktur-Namespaces
- Lösung: Nehmen Sie Namespaces wie
kube-system,kube-public,cosign-systemund andere Infrastruktur-Namespaces perexclude-Feld in der ClusterImagePolicy aus.
4. „Signature verification failed” trotz korrekt signiertem Image
- Ursache: Identity-Mismatch zwischen Signaturzertifikat und Policy-Konfiguration
- Lösung: Verwenden Sie
cosign verify --certificate-identity-regexpmit dem exakten Muster Ihrer Workflow-Identität. Prüfen Sie die Zertifikatsdetails mitcosign verify --output=text, um die tatsächlichen Identity-Claims zu sehen.
Compliance- und Audit-Aspekte
Die in diesem Leitfaden beschriebene Implementierung adressiert direkt regulatorische Anforderungen, die 2025 an Relevanz gewinnen — allen voran den EU Cyber Resilience Act (CRA), der Supply-Chain-Transparenz für Produkte mit Softwarekomponenten verpflichtend macht.
Das Rekor-Transparenzlog liefert einen unveränderlichen, ausschließlich anwachsenden Nachweis aller Signaturvorgänge. Jede Signaturoperation schreibt einen Eintrag nach Rekor, der Signatur, Zertifikat und Zeitstempel enthält. So entsteht ein kryptografisch verifizierbarer Audit-Trail, der nachträglich weder verändert noch gelöscht werden kann. Bei einer Incident-Untersuchung oder einem Compliance-Audit lässt sich in Rekor exakt nachvollziehen, wann ein Image von welcher Identität und unter welchen Umständen signiert wurde. Damit sind die Anforderungen an Provenance-Dokumentation erfüllt und Sie verfügen über belastbare forensische Belege für die Incident Response.
Der EU Cyber Resilience Act, 2024 in Kraft getreten und ab Dezember 2027 vollständig anwendbar, verpflichtet Hersteller von Produkten mit digitalen Elementen, die auf dem EU-Markt bereitgestellt werden. Der CRA verlangt maschinenlesbare SBOMs für alle Softwarekomponenten — mindestens auf Ebene der Top-Level-Abhängigkeiten. SBOMs werden dabei explizit als zentrale Werkzeuge für Schwachstellenverfolgung und Cybersecurity-Risikomanagement positioniert und ermöglichen es Herstellern wie Aufsichtsbehörden, schnell auf neu auftretende Bedrohungen zu reagieren. Eine öffentliche Veröffentlichung der SBOMs verlangt der CRA nicht, wohl aber die Bereitstellung an Marktüberwachungsbehörden auf Anfrage. Verstöße können mit Bußgeldern von bis zu 15 Millionen Euro oder 2,5 % des weltweiten Jahresumsatzes geahndet werden.
Fazit und nächste Schritte
Sie verfügen jetzt über eine Implementierung von Container Supply Chain Security, die auf Industriestandards aufsetzt. Ihre Umgebung umfasst:
- Einen GitHub-Actions-Workflow, der Container Images bei jedem Build automatisch signiert und in zwei Formaten SBOMs erzeugt
- Kryptografisch verifizierbare Provenance-Nachweise über die Keyless-Signing-Infrastruktur von Sigstore
- Maschinenlesbare Transparenz-Artefakte (SPDX- und CycloneDX-SBOMs), als Attestierungen an jedes Container Image angehängt
- Eine Enforcement-Schicht in Kubernetes, die Signaturen und Attestierungen vor jedem Deployment prüft
- Einen unveränderlichen Audit-Trail im Rekor-Transparenzlog für Compliance und Incident Response
- Eine belastbare Basis für die Erfüllung der Anforderungen des EU Cyber Resilience Act
Der Sicherheitsgewinn ist erheblich. Container-Deployments verlassen sich nicht mehr auf Vertrauen, sondern auf kryptografische Verifizierung. Schwachstellenmanagement stützt sich nicht mehr auf manuelle Nachverfolgung, sondern auf automatisierte SBOM-Auswertung. Und Compliance-Audits stützen sich nicht mehr allein auf Dokumentation, sondern auf unveränderliche Transparenzlogs mit verifizierbarem Beweiswert.
Weiterführende Ressourcen
Zum Vertiefen der hier gezeigten Konzepte und für weiterführende Umsetzungen:
In eigener Sache: CRA-Konformität erreichen Sie mit Kunnus, unserer Cyber-Resilience-Plattform für Fertigung, IoT und Industrie 4.0 — inklusive Supply Chain Security, SBOM-Management und Beratung rund um den EU Cyber Resilience Act.
Sigstore-Dokumentation (https://docs.sigstore.dev) — die autoritative Quelle für Cosign, Policy Controller und das gesamte Sigstore-Ökosystem. Über die Grundlagen dieses Leitfadens hinaus finden Sie dort Dokumentation zu eigenen Attestierungstypen für proprietäre Metadaten, zu Policy-Kompositionsmustern für Multi-Tenant-Cluster sowie Integrationsanleitungen für CI/CD-Plattformen jenseits von GitHub Actions. Die Referenzdokumentation umfasst detaillierte API-Spezifikationen und Troubleshooting-Anleitungen für Produktivbetriebe.
EU Cyber Resilience Act — Compliance-Informationen (https://digital-strategy.ec.europa.eu/en/library/cyber-resilience-act) — die offizielle CRA-Dokumentation der Europäischen Kommission, unverzichtbar für alle, die Produkte mit digitalen Elementen auf dem EU-Markt bereitstellen. Enthält technische Anhänge zu SBOM-Anforderungen, Fristen für Schwachstellenoffenlegungen und Verpflichtungen zu Security-Updates. Hersteller können damit ihre Supply-Chain-Security-Umsetzung konkret gegen einzelne CRA-Vorgaben mappen und Compliance-Nachweise für Marktüberwachungsbehörden vorbereiten.
Erweiterte Policy-Controller-Konfigurationen (https://docs.sigstore.dev/policy-controller/overview/) — vertiefte Auseinandersetzung mit den fortgeschrittenen Fähigkeiten von Policy Controller. Lernen Sie, wie sich mehrere Policies für unterschiedliche Image-Quellen kombinieren lassen, wie Sie eigene Validierungslogik mit CUE oder Rego umsetzen und wie sich externe Verifizierungsdienste anbinden lassen. Behandelt komplexe Szenarien wie die Verifikation gegen private Sigstore-Deployments, Policy-Vererbungshierarchien und das Monitoring der Policy-Wirksamkeit über Metriken und Alerts.
Integration von SBOM und Vulnerability-Scanning — erweitern Sie Ihre SBOM-Umsetzung um automatisierte Schwachstellenerkennung. Kombinieren Sie mit Syft erzeugte SBOMs mit Grype (https://github.com/anchore/grype) für ein umfassendes Vulnerability-Scanning, das CVEs gegen Ihre Softwarekomponenten abgleicht, oder mit Trivy (https://github.com/aquasecurity/trivy) für Multi-Scanner-Erkennung inklusive OS-Paketen, Sprach-Bibliotheken und Infrastructure-as-Code-Schwachstellen. Beide Tools verstehen SPDX und CycloneDX und lassen sich in CI/CD-Pipelines als automatisierte Security-Gates einbinden.