Eine Software Bill of Materials sagt, was in einem Image steckt. Sie sagt aber nicht, wer es gebaut hat und ob unterwegs jemand etwas ausgetauscht hat. Genau diese Lücke schließt eine Signatur. Wer Container-Images in eine Registry schiebt und sie später deployt, sollte beides haben: eine Stückliste und einen Nachweis der Herkunft. cosign aus dem Sigstore-Projekt macht das Signieren so einfach, dass die alte Ausrede vom Schlüssel-Management nicht mehr zieht.

Was cosign eigentlich absichert

Ein signiertes Image beantwortet zwei Fragen. Erstens: Stammt dieses Image wirklich aus meiner Pipeline und nicht aus einer kompromittierten Quelle? Zweitens: Ist der Inhalt seit dem Build unverändert, also Bit für Bit derselbe Digest? cosign legt die Signatur als zusätzliches Artefakt neben dem Image in dieselbe Registry. Es referenziert den Image-Digest, nicht das Tag. Das ist wichtig, weil ein Tag wie latest jederzeit auf ein anderes Image zeigen kann, der Digest aber eindeutig bleibt.

Keyless: signieren ohne langlebige Schlüssel

Der klassische Weg war ein privater Schlüssel, den man irgendwo sicher ablegen musste. Genau dieser Schlüssel ist das Problem, denn am Ende liegt er doch wieder als Secret in der Pipeline. Sigstore dreht das um. Beim keyless signing erzeugt cosign ein kurzlebiges Zertifikat, das an eine OIDC-Identität gebunden ist, zum Beispiel an den GitHub-Actions-Workflow, der gerade läuft. Das Zertifikat lebt nur wenige Minuten. Die Signatur landet zusammen mit einem Eintrag im öffentlichen Transparency Log Rekor. Es gibt keinen Schlüssel mehr, den man verlieren oder rotieren muss.

cosign sign --yes \
ghcr.io/meinorg/app@sha256:abcd1234ef56...

Ein kurzer Test geht auch lokal. Wer cosign installiert hat, signiert ein bereits gepushtes Image mit einem einzigen Befehl und bekommt im Browser eine OIDC-Anmeldung. Für die Pipeline ist das später vollautomatisch, aber der lokale Lauf hilft, den Ablauf einmal von Hand nachzuvollziehen.

Signieren in GitHub Actions

In der Pipeline braucht es nur zwei Dinge: die Berechtigung id-token: write, damit der Runner ein OIDC-Token bekommt, und den Digest des frisch gebauten Images. Den Digest liefert die docker/build-push-action direkt als Output.

permissions:
contents: read
packages: write
id-token: write
jobs:
build-sign:
runs-on: ubuntu-latest
steps:
- uses: sigstore/cosign-installer@v3
- name: Sign image
run: cosign sign --yes ${IMAGE}@${DIGEST}
env:
IMAGE: ghcr.io/meinorg/app
DIGEST: ${{ steps.build.outputs.digest }}

Wichtig ist, immer den Digest zu signieren und nicht den Tag. Ein Tag lässt sich überschreiben, der Digest steht fest.

Verifizieren, bevor etwas deployt wird

Signieren allein bringt nichts, wenn niemand prüft. Die Verifikation gehört an die Stelle, an der das Image in Betrieb geht.

cosign verify \
--certificate-identity-regexp "https://github.com/meinorg/.*" \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/meinorg/app@sha256:abcd1234ef56...

Die beiden Bedingungen sind der Kern: Das Image muss von einer Identität aus der eigenen GitHub-Organisation signiert sein und das Zertifikat muss vom erwarteten OIDC-Issuer stammen. Ohne diese Einschränkungen prüft man nur, dass irgendjemand signiert hat, und das ist wertlos. Im Cluster lässt sich dieselbe Regel mit einem Admission Controller wie Kyverno oder dem Sigstore Policy Controller erzwingen, sodass unsignierte Images gar nicht erst starten.

Was das praktisch kostet

Der Aufwand ist gering. Ein Installer-Step, eine Berechtigung, eine Zeile zum Signieren und eine Verifikationsregel. Kein Vault, keine Schlüsselrotation, kein Secret das altert. Der Gewinn ist eine nachvollziehbare Kette: Dieses Image kam aus diesem Commit, gebaut von diesem Workflow, unverändert bis zum Deploy. Zusammen mit einer SBOM hat man damit die zwei Bausteine, die in jeder ernsthaften Lieferketten-Diskussion zuerst genannt werden.

Ein Punkt wird gern übersehen: Die Verifikation muss scheitern dürfen. Wenn ein nicht signiertes oder falsch signiertes Image den Deploy trotzdem passiert, weil die Regel nur warnt, ist die ganze Kette wertlos. Setzt die Prüfung als harte Bedingung, nicht als Hinweis.

Signaturen und Stücklisten sind kein Selbstzweck. Interessant werden sie, sobald ein Kunde oder ein Prüfer fragt, woher eine Software stammt. Wie sich solche Nachweise sauber in eine Pipeline einbauen lassen, ohne dass das Team im Tooling versinkt, ist auch regelmäßig Thema auf digital-business.blog.

Hinterlasse einen Kommentar

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..