Container Images mit Notation signieren
Wer Container Images aus einer Registry bezieht, verlässt sich darauf, dass Inhalt und Herkunft stimmen. Signaturen machen das prüfbar: Sie binden einen Image-Digest an einen Aussteller und schützen so vor Manipulation zwischen Push und Pull.
Im OSS-Umfeld ist dafür meist Cosign aus dem Sigstore-Projekt im Einsatz, das wir in einem eigenen Beitrag behandelt haben.
Cosign ist aber nicht das einzige praxisrelevante Werkzeug.
Dieser Beitrag stellt die zweite verbreitete Option vor: Notation aus dem Notary Project.
Von Docker Content Trust zu Notation
Der historische Ansatz war Docker Content Trust (DCT), eine Implementierung von TUF (The Update Framework). DCT war Docker-spezifisch und legte Signaturen nicht in der Registry ab, sondern auf einem separaten Notary-Server. Docker hat DCT im Juli 2025 abgekündigt, in aktuellen Docker-Versionen ist der Unterbefehl bereits entfernt:
$ docker trust inspect alpine:3.20
docker: unknown command: docker trust
Der Nachfolger im Notary Project heißt Notation und wird oft als Notary v2 bezeichnet. Notation hat TUF hinter sich gelassen und setzt auf ein zertifikatsbasiertes X.509-/PKI-Modell. Die Signatur wird als eigenes OCI-Artefakt im selben Repository abgelegt, ein separater Trust-Server entfällt.
Notation ist ein CNCF-Projekt, das primär von Microsoft und AWS getragen wird, und in Azure Container Registry sowie bei AWS nativ integriert ist.
Die Einsatzbereiche lassen sich grob wie folgt klassifizieren:
Cosign für Open-Source-Projekte und einen schlüssellosen (keyless) Ablauf, Notation für Umgebungen mit bestehender PKI und Zertifikatsverwaltung.
The Update Framework (TUF)
TUF ist kein Signaturwerkzeug, sondern eine Spezifikation zur Absicherung ganzer Software-Update-Systeme. Sie beschreibt, wie ein Repository und seine Metadaten aufgebaut sein müssen, damit Clients Updates sicher beziehen können. Der Schutz geht dabei über eine einzelne Signatur hinaus: TUF verteilt das Vertrauen auf mehrere Rollen mit getrennten Schlüsseln (root, targets, snapshot, timestamp). Dadurch bleibt der Schaden bei Kompromittierung eines einzelnen Schlüssels begrenzt, und Angriffe wie das Zurückspielen alter, verwundbarer Versionen oder das Einfrieren von Updates lassen sich erkennen.
TUF entstand an der New York University im Secure Systems Lab um Justin Cappos und ist seit 2011 dort angesiedelt. Seit Dezember 2019 ist es ein Graduated Project der CNCF und war dort das erste Sicherheitsprojekt sowie das erste von einem akademischen Forscher geführte Projekt mit diesem Status. Neben der Spezifikation gibt es Referenzimplementierungen wie python-tuf und go-tuf.
Für die Signatur einzelner Container Images spielt TUF heute kaum noch eine direkte Rolle. Die TUF-basierte Umsetzung Docker Content Trust ist abgekündigt, und Notation setzt bewusst auf das einfachere PKI-Modell. Als Fundament für die sichere Verteilung ganzer Artefaktsammlungen ist TUF aber weiterhin verbreitet. Es sichert unter anderem die Paketverteilung im Python Package Index (PyPI), den Vertrauensanker (Root of Trust) von Sigstore und, in der Uptane-Variante, Over-the-Air-Updates in Fahrzeugen. Für Cosign bedeutet das: Das Werkzeug selbst signiert ohne TUF, sein Root of Trust wird jedoch über TUF verteilt.
Signieren mit Notation
Notation ist ein eigenständiges CLI (Notary Project), das gegen jede OCI-konforme Registry arbeitet.
Für das Beispiel liegt ein Image in einer lokalen Registry.
Weil diese über HTTP läuft, wird --insecure-registry gesetzt.
Zunächst wird ein Signaturschlüssel benötigt. Für einen schnellen Test erzeugt Notation ein selbstsigniertes Zertifikat und legt es zugleich als Vertrauensanker ab. In der Praxis stammt das Zertifikat aus der eigenen PKI.
$ notation cert generate-test "trion.example.com"
generating RSA Key with 2048 bits
generated certificate expiring on 2026-07-05T18:56:15Z
wrote key: ~/.config/notation/localkeys/trion.example.com.key
wrote certificate: ~/.config/notation/localkeys/trion.example.com.crt
Successfully added trion.example.com.crt to named store trion.example.com of type ca
trion.example.com: added to the key list
Anschließend wird das Image signiert.
Notation löst den Tag zum Digest auf und legt die Signatur als OCI-Artefakt vom Typ application/vnd.cncf.notary.signature neben dem Image ab.
$ notation key set --default trion.example.com
$ notation sign --insecure-registry localhost:5000/demo/app:1.0
Successfully signed localhost:5000/demo/app@sha256:6c2a...987c
$ notation ls --insecure-registry localhost:5000/demo/app:1.0
localhost:5000/demo/app@sha256:6c2a...987c
└── application/vnd.cncf.notary.signature
└── sha256:cbe2c294...064b
Das Signatur-Artefakt ist als eigener Eintrag im Repository sichtbar:
$ curl -s http://localhost:5000/v2/demo/app/tags/list
{"name":"demo/app","tags":["1.0","sha256-6c2a...987c"]}
Validierung
Notation prüft Signaturen nicht gegen einen einzelnen Schlüssel, sondern gegen eine Trust Policy.
Sie legt fest, für welche Registries welche Vertrauensanker und Identitäten gelten.
Die folgende Policy vertraut dem oben angelegten Zertifikat.
Die Wildcards bei registryScopes und trustedIdentities sind für das Beispiel gewählt und werden produktiv auf konkrete Registries und Zertifikatsinhaber eingegrenzt.
{
"version": "1.0",
"trustPolicies": [
{
"name": "trion-demo",
"registryScopes": [ "*" ],
"signatureVerification": { "level": "strict" },
"trustStores": [ "ca:trion.example.com" ],
"trustedIdentities": [ "*" ]
}
]
}
Nach dem Import der Policy lässt sich das Image verifizieren.
$ notation policy import trustpolicy.json
Trust policy configuration imported successfully.
$ notation verify --insecure-registry localhost:5000/demo/app:1.0
Successfully verified signature for localhost:5000/demo/app@sha256:6c2a...987c
Ein unsigniertes oder manipuliertes Image fällt dabei durch:
$ notation verify --insecure-registry localhost:5000/demo/unsigned:1.0
Error: signature verification failed: no signature is associated with
"localhost:5000/demo/unsigned@sha256:...", make sure the artifact was signed successfully
In Kubernetes übernimmt diese Prüfung ein Admission Controller. Für das Notary Project gibt es dazu Ratify, das signierte Images beim Deployment gegen die Trust Policy verifiziert und unsignierte ablehnt.
Fazit
Der TUF-basierte Ansatz von Notary v1 beziehungsweise Docker Content Trust ist abgekündigt und in aktuellen Docker-Versionen nicht mehr nutzbar. An seine Stelle sind zwei OCI-native Verfahren getreten, die Signaturen ohne separate Infrastruktur direkt in der Registry ablegen: Notation aus dem Notary Project und Cosign aus dem Sigstore-Umfeld.
Welches Werkzeug passt, hängt vom Vertrauensmodell ab.
Ein bestehendes PKI- und Zertifikats-Setup spricht für Notation, ein schlüsselloser Ablauf mit Transparenz-Log für Cosign.
Details und ein vollständiges Beispiel zu Cosign finden sich im separaten Beitrag.
Wichtig ist in beiden Fällen, die Validierung verpflichtend zu machen, etwa im CI/CD-Prozess und über einen Admission Controller im Cluster.
Zu den Themen Kubernetes, Docker und Cloudarchitektur bieten wir sowohl Beratung, Entwicklungsunterstützung als auch passende Schulungen an:
Auch für Ihren individuellen Bedarf können wir Workshops und Schulungen anbieten. Sprechen Sie uns gerne an.