Veröffentlicht am

Container Image Signing: Sigstore und Cosign nutzen

Teilen:
Authors

TL;DR

Cosign aus dem Sigstore-Projekt signiert Container Images kryptografisch — entweder mit eigenem Key oder keyless per OIDC. Kombiniert mit einer Kyverno-ClusterPolicy blockst du unsignierte Images automatisch im Cluster. Das schützt die Software Supply Chain ohne komplexe PKI-Infrastruktur.


Container Images signieren mit Cosign

Jedes kubectl apply zieht potenziell unsichere Images in deinen Cluster. Woher weißt du, dass das Image tatsächlich von deiner CI/CD-Pipeline stammt und nicht manipuliert wurde? Container Image Signing löst genau dieses Problem.

# Cosign installieren
brew install cosign
# oder
go install github.com/sigstore/cosign/v2/cmd/cosign@latest

cosign version

Wie Sigstore funktioniert

Sigstore ist ein Open-Source-Ökosystem für Software Signing. Die Kernkomponenten:

  • Cosign — signiert und verifiziert Container Images und andere OCI-Artefakte
  • Fulcio — kurzlebige Zertifikats-Authority für keyless Signing
  • Rekor — Transparency Log, das alle Signaturen unveränderlich speichert

Der entscheidende Vorteil gegenüber klassischem GPG-Signing: Kein langlebiger Private Key, der geschützt und rotiert werden muss.

Signing mit eigenem Schlüsselpaar

Für den Einstieg oder Air-Gapped-Umgebungen:

# Schlüsselpaar generieren
cosign generate-key-pair

# Image signieren
cosign sign --key cosign.key registry.example.com/app:v1.2.3

# Signatur verifizieren
cosign verify --key cosign.pub registry.example.com/app:v1.2.3

Die Signatur wird als OCI-Artefakt neben dem Image in der Registry gespeichert. Kein separater Signatur-Server nötig.

Keyless Signing mit OIDC

In CI/CD-Pipelines ist keyless Signing der bessere Weg. Cosign nutzt dabei einen OIDC-Token (z.B. von GitHub Actions, GitLab CI oder Google) und lässt sich von Fulcio ein kurzlebiges Zertifikat ausstellen.

# Keyless Signing (interaktiv — öffnet Browser für OIDC)
cosign sign registry.example.com/app:v1.2.3

# In GitHub Actions (automatisch via OIDC)
# Kein Key nötig, der GITHUB_TOKEN reicht
cosign sign --yes ghcr.io/org/app:${{ github.sha }}

Die Verifizierung prüft dann gegen die OIDC-Identität:

# Verifizierung mit Identitätsprüfung
cosign verify \
  --certificate-identity "https://github.com/org/app/.github/workflows/build.yml@refs/heads/main" \
  --certificate-oidc-issuer "https://token.actions.githubusercontent.com" \
  ghcr.io/org/app:v1.2.3
MethodeVorteileNachteile
Key-PairOffline nutzbar, volle KontrolleKey-Management erforderlich
Keyless OIDCKein Key-Management, CI/CD-IntegrationInternet-Zugang zu Fulcio/Rekor nötig

CI/CD-Integration: GitHub Actions

Ein vollständiges Workflow-Beispiel für automatisches Signing:

# .github/workflows/build-sign.yml
name: Build and Sign
on:
  push:
    tags: ['v*']

permissions:
  contents: read
  packages: write
  id-token: write  # Nötig für keyless Signing

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: sigstore/cosign-installer@v3

      - name: Build and Push
        run: |
          docker build -t ghcr.io/${{ github.repository }}:${{ github.ref_name }} .
          docker push ghcr.io/${{ github.repository }}:${{ github.ref_name }}

      - name: Sign Image
        run: |
          cosign sign --yes \
            ghcr.io/${{ github.repository }}:${{ github.ref_name }}

Kyverno: Unsignierte Images blockieren

Signing allein reicht nicht — du brauchst Enforcement im Cluster. Kyverno als Admission Controller prüft bei jedem Pod-Create, ob das Image signiert ist.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signatures
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: verify-cosign-signature
      match:
        any:
          - resources:
              kinds:
                - Pod
      verifyImages:
        - imageReferences:
            - "ghcr.io/org/*"
            - "registry.example.com/*"
          attestors:
            - entries:
                - keyless:
                    subject: "https://github.com/org/*"
                    issuer: "https://token.actions.githubusercontent.com"
                    rekor:
                      url: https://rekor.sigstore.dev

Was passiert damit:

  • Pods mit Images aus ghcr.io/org/* werden nur zugelassen, wenn eine gültige Cosign-Signatur existiert
  • Die Signatur muss von einem GitHub-Actions-Workflow aus der Organisation org stammen
  • Unsignierte oder falsch signierte Images werden abgelehnt
# Policy anwenden
kubectl apply -f verify-image-signatures.yaml

# Test: Unsigniertes Image wird blockiert
kubectl run test --image=ghcr.io/org/unsigned-app:latest
# Error: image verification failed

Rekor: Transparency Log prüfen

Jede Signatur landet im öffentlichen Rekor Transparency Log. Das ist auditierbar:

# Alle Signaturen für ein Image im Transparency Log finden
cosign verify --certificate-identity="*" \
  --certificate-oidc-issuer="*" \
  ghcr.io/org/app:v1.2.3 2>/dev/null | jq .

# Rekor-Einträge direkt durchsuchen
rekor-cli search --email user@example.com

FAQ

Brauche ich Sigstore oder reicht Docker Content Trust (DCT)?

Docker Content Trust basiert auf Notary v1 und wird kaum noch weiterentwickelt. Sigstore/Cosign ist der De-facto-Standard mit breiter Tooling-Unterstützung (Kyverno, OPA Gatekeeper, Kubernetes Policy Controller). Für neue Projekte ist Cosign die bessere Wahl.

Was kostet Sigstore?

Nichts. Die öffentliche Infrastruktur (Fulcio, Rekor) wird von der Linux Foundation betrieben und ist kostenlos nutzbar. Für Air-Gapped-Umgebungen kannst du eigene Instanzen betreiben.

Funktioniert Cosign mit jeder Container Registry?

Cosign funktioniert mit jeder OCI-kompatiblen Registry — Docker Hub, GHCR, ECR, GCR, ACR, Harbor, Quay. Die Signatur wird als eigenes OCI-Artefakt im selben Repository gespeichert.

Wie sichere ich die Signatur-Verifizierung gegen Ausfälle ab?

Für Production solltest du einen Rekor-Mirror oder eine eigene Sigstore-Instanz betreiben. Die Kyverno-Policy kann außerdem einen Fallback-Attestor mit statischem Public Key enthalten.


Nächster Schritt: Kombiniere Image Signing mit Runtime Security via Falco, um sowohl die Supply Chain als auch das Laufzeitverhalten deiner Container abzusichern.

Kubernetes-Security & Compliance?

Security-Audits, Penetration Tests und Compliance-Beratung für Ihre Container-Infrastruktur. BSI-Grundschutz, DSGVO, ISO 27001.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen