
Codesignierung und Transparenz für Container und Binärdateien
Signieren von OCI-Containern (und anderen Artefakten) mit Sigstore!
Cosign zielt darauf ab, Signaturen zu unsichtbarer Infrastruktur zu machen.
Cosign unterstützt:
Cosign wird als Teil des sigstore-Projekts entwickelt.
Wir nutzen auch einen Slack-Kanal!
Klicken Sie hier für den Einladungslink.
Für Installationen mit Homebrew, Arch, Nix, GitHub Action und Kubernetes siehe die Installationsdokumentation.
Für Linux- und macOS-Binärdateien siehe die GitHub-Release-Assets.
🚨 Wenn Sie Releases von cosign aus unserem GCS-Bucket herunterladen, finden Sie weitere Informationen im Hinweis zur Einstellung vom 31. Juli 2023 🚨
Wenn Sie Go 1.22+ haben, können Sie eine Entwicklungsumgebung einrichten:```shell $ git clone https://github.com/sigstore/cosign $ cd cosign $ go install ./cmd/cosign $ $(go env GOPATH)/bin/cosign
## Contributing
Wenn Sie daran interessiert sind, zu `cosign` beizutragen, lesen Sie bitte die [Contributing-Dokumentation](https://github.com/sigstore/cosign/blob/HEAD/CONTRIBUTING.md).
Die zukünftige Cosign-Entwicklung wird sich auf das nächste große Release konzentrieren, das auf
[sigstore-go](https://github.com/sigstore/sigstore-go) basieren wird. Die Maintainer werden sich auf die Feature-Entwicklung innerhalb von
sigstore-go konzentrieren. Beiträge zu sigstore-go, insbesondere rund um Bring-your-own-Keys und Signierung, sind willkommen.
Bitte werfen Sie einen Blick auf den [Issue-Tracker](https://github.com/sigstore/sigstore-go/issues) für geeignete erste Issues.
Cosign 2.x ist ein stabiles Release und wird weiterhin regelmäßig Feature-Updates und Bugfixes erhalten. PRs
mit kleinem Umfang und geringer Größe werden am ehesten schnell überprüft.
PRs, die die API erheblich verändern oder brechen, werden nicht angenommen. PRs, die einen erheblichen Umfang haben, aber keine
Breaking Changes einführen, können angenommen werden, werden jedoch als weniger prioritär eingestuft als PRs in sigstore-go.
## Dockerfile
Hier ist, wie man cosign in einem Dockerfile über das Image ghcr.io/sigstore/cosign/cosign installiert und verwendet:```shell
FROM ghcr.io/sigstore/cosign/cosign:v2.4.1 as cosign-bin
# Source: https://github.com/chainguard-images/static
FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
Dies zeigt, wie man:
Beachte, dass du Images immer anhand ihres Digests (@sha256:...) signieren solltest
und nicht anhand eines Tags (:latest), da du sonst möglicherweise etwas signierst,
das du nicht beabsichtigt hast!```shell
cosign sign $IMAGE
Generating ephemeral keys... Retrieving signed certificate...
Note that there may be personally identifiable information associated with this signed artifact.
This may include the email address associated with the account with which you authenticate.
This information will be used for signing this artifact and will be stored in public transparency logs and cannot be removed later.
By typing 'y', you attest that you grant (or have permission to grant) and agree to have this information stored permanently in transparency logs. Are you sure you would like to continue? [y/N] y Your browser will now be opened to: https://oauth2.sigstore.dev/auth/auth?access_type=online&client_id=sigstore&code_challenge=OrXitVKUZm2lEWHVt1oQWR4HZvn0rSlKhLcltglYxCY&code_challenge_method=S256&nonce=2KvOWeTFxYfxyzHtssvlIXmY6Jk&redirect_uri=http%3A%2F%2Flocalhost%3A57102%2Fauth%2Fcallback&response_type=code&scope=openid+email&state=2KvOWfbQJ1caqScgjwibzK2qJmb Successfully verified SCT... tlog entry created with index: 12086900 Pushing signature to: $IMAGE
Cosign wird Sie auffordern, sich über OIDC zu authentifizieren, wobei Sie sich mit Ihrer E-Mail-Adresse anmelden.
Im Hintergrund fordert cosign ein Codesignatur-Zertifikat von der Zertifizierungsstelle Fulcio an.
Das Subject des Zertifikats stimmt mit der E-Mail-Adresse überein, mit der Sie sich angemeldet haben.
Cosign speichert dann die Signatur und das Zertifikat im Rekor-Transparenzprotokoll und lädt die Signatur zusammen mit dem Image, das Sie signieren, in die OCI-Registry hoch.
### Einen Container verifizieren
Um das Image zu verifizieren, müssen Sie den erwarteten Zertifikats-Subject und den Zertifikatsaussteller über die Flags `--certificate-identity` und `--certificate-oidc-issuer` angeben:```
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
Sie können auch einen regulären Ausdruck für die Zertifikatsidentität und die Issuer-Flags übergeben, --certificate-identity-regexp und --certificate-oidc-issuer-regexp.
Dieser Befehl gibt 0 zurück, wenn mindestens eine cosign-formatierte Signatur für das Image gefunden wird,
die zum öffentlichen Schlüssel passt.
Weitere Informationen und Hinweise zu anderen Signaturformaten finden Sie in der detaillierten Verwendung unten.
Alle gültigen Payloads werden im JSON-Format auf stdout ausgegeben. Beachten Sie, dass diese signierten Payloads den Digest des Container-Images enthalten – so können wir sicher sein, dass diese "abgelösten" Signaturen das richtige Image abdecken.```shell $ cosign verify --key cosign.pub $IMAGE_URI:1h The following checks were performed on these signatures:
### Verifizieren eines Containers in einer Air-Gapped-Umgebung
**Hinweis:** Dieser Abschnitt ist veraltet.
**Hinweis:** Die meisten Verifizierungsabläufe erfordern, dass regelmäßig Dienstschlüssel von einem TUF-Repository angefordert werden.
Für die Air-Gapped-Verifizierung von Signaturen mithilfe der Public-Good-Instanz müssen Sie die Datei
[trusted root](https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json) aus dem Produktions-
TUF-Repository abrufen. Der Inhalt dieser Datei kann sich ohne Vorankündigung ändern. Wenn Sie TUF nicht verwenden, müssen Sie
einen eigenen Mechanismus aufbauen, um Ihre Air-Gapped-Kopie dieser Datei aktuell zu halten.
Cosign kann eine vollständige Offline-Verifizierung durchführen, indem es ein [Bundle](https://github.com/sigstore/cosign/blob/HEAD/specs/SIGNATURE_SPEC.md#properties) verifiziert, das normalerweise als Annotation im Image-Manifest verteilt wird.
Solange diese Annotation vorhanden ist, kann die Offline-Verifizierung durchgeführt werden.
Diese Bundle-Annotation ist standardmäßig immer bei schlüssellosem Signieren enthalten, sodass die Standardfunktion `cosign sign` alle Materialien enthält, die für die Offline-Verifizierung benötigt werden.
Um ein Image in einer Air-Gapped-Umgebung zu verifizieren, müssen das Image und die Signaturen lokal im Dateisystem verfügbar sein.
Ein Image kann mit `cosign save` lokal gespeichert werden (Hinweis: Dieser Schritt muss mit einer Netzwerkverbindung durchgeführt werden):```
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
Nun kann dieses lokale Image in einer air-gapped Umgebung verifiziert werden:```shell
cosign verify
--certificate-identity $CERT_IDENTITY
--certificate-oidc-issuer $CERT_OIDC_ISSUER
--offline=true
--new-bundle-format=false \ # for artifacts signed without the new protobuf bundle format
--trusted-root ~/.sigstore/root/tuf-repo-cdn.sigstore.dev/targets/trusted_root.json \ # default location of trusted root
--local-image ./path/to/dir
Sie müssen erwartete Werte für `$CERT_IDENTITY` und `$CERT_OIDC_ISSUER` übergeben, um dieses Image korrekt zu verifizieren.
Wenn Sie mit einem Schlüsselpaar signiert haben, funktioniert derselbe Befehl, sofern das öffentliche Schlüsselmaterial lokal vorhanden ist:```
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
Verwenden Sie die schlüssellose Blob-Signierung (cosign sign-blob ohne --key) und verifizieren Sie gegen die erwartete Signierer-Identität:```shell
$ cosign sign-blob artifact --bundle artifact.sigstore.json --yes
$ cosign verify-blob artifact
--bundle artifact.sigstore.json
--certificate-identity "https://github.com/ORG/REPO/.github/workflows/release.yml@refs/heads/main"
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
### Fehlerbehebung
Wenn Sie Probleme mit Cosign haben, stellen Sie zunächst sicher, dass Sie eine aktuelle Version verwenden: Das Cosign-Projekt unterstützt aktiv die neueste Version sowie die letzte Version der v2-Serie.
#### Häufige Probleme und Abhilfen
1. Verifizierung schlägt fehl mit `failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1`: Möglicherweise verifizieren Sie eine Signatur, die RFC3161-Zeitstempelunterstützung erfordert
* Aktualisieren Sie auf die neueste Cosign-Version oder
* Verwenden Sie bei Cosign 2.6.x `--use-signed-timestamps`
1. Verifizierung schlägt fehl mit `no signatures found`: Möglicherweise verifizieren Sie eine Image-Signatur, die Unterstützung für das Rekor-v2-Transparenzlog erfordert
* Aktualisieren Sie auf die neueste Cosign-Version
1. Signieren schlägt mit HTTP-Fehlern fehl: Das Signieren mit Cosign hängt von mehreren Sigstore-Diensten ab. Ein erneuter Versuch nach einem Fehler kann eine nützliche Problemumgehung sein, wenn einer dieser Dienste ausfällt – das Melden von Issues für spezifische Fehler wird ebenfalls geschätzt
#### Mein Problem ist etwas anderes
Bitte öffnen Sie ein [Issue](https://github.com/sigstore/cosign/issues/new/choose) oder fragen Sie im [Slack-Kanal](#info).
## Arbeiten mit anderen Artefakten
OCI-Registries sind nützlich, um mehr als nur Container-Images zu speichern!
`Cosign` enthält außerdem einige Hilfsprogramme zum Veröffentlichen generischer Artefakte, einschließlich Binärdateien, Skripten und Konfigurationsdateien, die das OCI-Protokoll verwenden.
Dieser Abschnitt zeigt, wie Sie diese für ein benutzerfreundliches, abwärtskompatibles Artefaktverteilungssystem nutzen können, das gut mit dem Rest von Sigstore integriert ist.
Weitere Informationen finden Sie in [der Dokumentation](https://docs.sigstore.dev/cosign/signing/other_types/).
### Blobs
Sie können ein Artefakt mit `cosign upload blob` veröffentlichen:```shell
$ echo "my first artifact" > artifact
$ BLOB_SUM=$(shasum -a 256 artifact | cut -d' ' -f 1) && echo "$BLOB_SUM"
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626
$ BLOB_NAME=my-artifact-$(uuidgen | head -c 8 | tr 'A-Z' 'a-z')
$ BLOB_URI=ttl.sh/$BLOB_NAME:1h
$ BLOB_URI_DIGEST=$(cosign upload blob -f artifact $BLOB_URI) && echo "$BLOB_URI_DIGEST"
Uploading file from [artifact] to [ttl.sh/my-artifact-f42c22e0:5m] with media type [text/plain]
File [artifact] is available directly at [ttl.sh/v2/my-artifact-f42c22e0/blobs/sha256:c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626]
Uploaded image to:
ttl.sh/my-artifact-f42c22e0@sha256:790d47850411e902aabebc3a684eeb78fcae853d4dd6e1cc554d70db7f05f99f
Ihre Benutzer können es von der "direkten" URL mit Standard-Tools wie curl oder wget herunterladen:```shell $ curl -L ttl.sh/v2/$BLOB_NAME/blobs/sha256:$BLOB_SUM > artifact-fetched
Der Digest ist direkt in die URL eingebettet, sodass sie das ebenfalls überprüfen können:```shell
$ cat artifact-fetched | shasum -a 256
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626 -
Sie können es mit dem normalen Befehl cosign sign und den Flags signieren:```shell
$ cosign sign --key cosign.key $BLOB_URI_DIGEST
Enter password for private key:
Pushing signature to: ttl.sh/my-artifact-f42c22e0
Wie immer solltest du sicherstellen, dass du Bilder, die du signierst, anhand ihres Digests referenzierst, damit du nicht das Falsche signierst!
#### Tekton Bundles
[Tekton](https://tekton.dev)-Bundles können in einer OCI-Registry hochgeladen und verwaltet werden.
Die Spezifikation ist [hier](https://tekton.dev/docs/pipelines/tekton-bundle-contracts/).
Das bedeutet, dass sie auch mit `cosign` signiert und verifiziert werden können.
Tekton-Bundles können derzeit mit dem [tkn cli](https://github.com/tektoncd/cli) hochgeladen werden, aber wir werden diese Unterstützung möglicherweise in Zukunft zu `cosign` hinzufügen.```shell
$ tkn bundle push us.gcr.io/dlorenc-vmtest2/pipeline:latest -f task-output-image.yaml
Creating Tekton Bundle:
- Added TaskRun: to image
Pushed Tekton Bundle to us.gcr.io/dlorenc-vmtest2/pipeline@sha256:124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155
$ cosign sign --key cosign.key us.gcr.io/dlorenc-vmtest2/pipeline@sha256:124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155
Enter password for private key:
tlog entry created with index: 5086
Pushing signature to: us.gcr.io/dlorenc-vmtest2/demo:sha256-124e1fdee94fe5c5f902bc94da2d6e2fea243934c74e76c2368acdc8d3ac7155.sig
WebAssembly-Module können auch in einer OCI-Registry gespeichert werden, mithilfe dieser Spezifikation.
Cosign kann diese mit dem Befehl cosign wasm upload hochladen:```shell
$ cosign upload wasm -f hello.wasm us.gcr.io/dlorenc-vmtest2/wasm
$ cosign sign --key cosign.key us.gcr.io/dlorenc-vmtest2/wasm@sha256:9e7a511fb3130ee4641baf1adc0400bed674d4afc3f1b81bb581c3c8f613f812
Enter password for private key:
tlog entry created with index: 5198
Pushing signature to: us.gcr.io/dlorenc-vmtest2/wasm:sha256-9e7a511fb3130ee4641baf1adc0400bed674d4afc3f1b81bb581c3c8f613f812.sig
#### eBPF
[eBPF](https://ebpf.io)-Module können ebenfalls in einer OCI-Registry gespeichert werden, mithilfe dieser [Spezifikation](https://github.com/solo-io/bumblebee/tree/main/spec).
Das untenstehende Bild wurde mit dem `bee`-Tool erstellt. Weitere Informationen finden Sie [hier](https://github.com/solo-io/bumblebee/)
Cosign kann dann diese Images genauso signieren wie jedes andere OCI-Image.```shell
$ bee build ./examples/tcpconnect/tcpconnect.c localhost:5000/tcpconnect:test
$ bee push localhost:5000/tcpconnect:test
$ cosign sign --key cosign.key localhost:5000/tcpconnect@sha256:7a91c50d922925f152fec96ed1d84b7bc6b2079c169d68826f6cf307f22d40e6
Enter password for private key:
Pushing signature to: localhost:5000/tcpconnect
$ cosign verify --key cosign.pub localhost:5000/tcpconnect:test
Verification for localhost:5000/tcpconnect:test --
The following checks were performed on each of these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
[{"critical":{"identity":{"docker-reference":"localhost:5000/tcpconnect"},"image":{"docker-manifest-digest":"sha256:7a91c50d922925f152fec96ed1d84b7bc6b2079c169d68826f6cf307f22d40e6"},"type":"cosign container image signature"},"optional":null}]
Cosign bietet auch integrierte Unterstützung für in-toto-Attestationen. Die Spezifikation dafür ist hier definiert.
Sie können eine aus einer lokalen Predicate-Datei mit den folgenden Befehlen erstellen und signieren:```shell $ cosign attest --predicate --key cosign.key $IMAGE_URI_DIGEST
Alle gängigen Schlüsselverwaltungssysteme werden unterstützt.
Payloads werden mit der DSSE-Signaturspezifikation signiert, die [hier](https://github.com/secure-systems-lab/dsse) definiert ist.
Um zu verifizieren:```shell
$ cosign verify-attestation --key cosign.pub $IMAGE_URI
Weitere Informationen finden Sie in der Verwendungsdokumentation.
Informationen zur Verwendung von cosign mit Hardware finden Sie in der Dokumentation zu Hardware-Token.
cosign verwendet go-containerregistry für Registry-Interaktionen, das im Allgemeinen eine hervorragende Kompatibilität aufweist, aber einige Registries können Eigenheiten haben.
Derzeit wurde cosign mit den folgenden Registries getestet und funktioniert mit ihnen:
Wir streben eine breite Registry-Unterstützung an. Zum Signieren von Images in Registries, die die OCI-Medientypen noch nicht vollständig unterstützen, muss möglicherweise COSIGN_DOCKER_MEDIA_TYPES verwendet werden, um auf veraltete Äquivalente zurückzugreifen. Zum Beispiel:```shell
COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image@$DIGEST
Bitte hilf mit, teste und melde Fehler, wenn du Probleme siehst!
Anweisungen findest du im [Tracking-Issue](https://github.com/sigstore/cosign/issues/40).
## Einschränkungen
### Absichtlich fehlende Funktionen
`cosign` erzeugt nur ECDSA-P256-Schlüssel und verwendet SHA256-Hashes, sowohl für ephemeres schlüsselloses Signieren als auch für das Signieren mit verwalteten Schlüsseln.
Schlüssel werden im PEM-kodierten PKCS8-Format gespeichert.
Du kannst `cosign` jedoch verwenden, um Signaturen in jedem Format und von jedem Algorithmus zu speichern und abzurufen.
### Dinge, die sich wahrscheinlich ändern sollten
#### Nutzlastformate
`cosign` unterstützt für Nutzlasten nur das [simple signing](https://www.redhat.com/en/blog/container-image-signing)-Format von Red Hat.
Das sieht wie folgt aus:```json
{
"critical": {
"identity": {
"docker-reference": "testing/manifest"
},
"image": {
"Docker-manifest-digest": "sha256:20be...fe55"
},
"type": "cosign container image signature"
},
"optional": {
"creator": "Bob the Builder",
"timestamp": 1458239713
}
}
Hinweis: Dies kann für eine Bildreferenz mit cosign generate $IMAGE_URI_DIGEST erzeugt werden.
Ich bin gerne bereit, dieses Format gegen etwas anderes auszutauschen, falls das sinnvoll ist. Siehe https://github.com/notaryproject/nv2/issues/40 für eine Option.
cosign-Signaturen werden als separate Objekte in der OCI-Registry gespeichert, mit nur einer schwachen Referenz zurück auf das Objekt, das sie „signieren“.
Das bedeutet, dass diese Beziehung für die Registry undurchsichtig ist und Signaturen nicht gelöscht oder der Garbage Collection zugeführt werden, wenn das Bild gelöscht wird.
Ebenso können sie leicht von einer Umgebung in eine andere kopiert werden, aber dies geschieht nicht automatisch.
Mehrere Signaturen werden in einer Liste gespeichert, was heute leider eine Race Condition darstellt. Um eine Signatur hinzuzufügen, orchestrieren Clients eine „read-append-write“-Operation, sodass bei Konflikten der letzte Schreibvorgang gewinnt.
cosign speichert Signaturen standardmäßig in demselben Repository wie das Bild, das es signiert.
Um ein anderes Repository für Signaturen anzugeben, können Sie die Umgebungsvariable COSIGN_REPOSITORY setzen.
Dadurch wird das Repository im angegebenen Bild wie folgt ersetzt:```shell $ export COSIGN_REPOSITORY=gcr.io/my-new-repo $ cosign sign --key cosign.key $IMAGE_URI_DIGEST
So the signature for `gcr.io/dlorenc-vmtest2/demo` will be stored in `gcr.io/my-new-repo/demo:sha256-DIGEST.sig`.
Hinweis: Unterschiedliche Registries erwarten möglicherweise unterschiedliche Formate für das „Repository“.
* Für die Verwendung von [GCR](https://cloud.google.com/container-registry) reicht ein
Registriername wie `gcr.io/$REPO`, wie im obigen Beispiel.
* Für die Verwendung von [Artifact Registry](https://cloud.google.com/artifact-registry)
gib einen vollständigen Imagenamen wie
`$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE` an, nicht nur ein
Repository. Zum Beispiel, ```shell
$ export COSIGN_REPOSITORY=us-docker.pkg.dev/my-new-repo/demo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
wobei der sha256-DIGEST mit dem Digest für
gcr.io/dlorenc-vmtest2/demo übereinstimmt. Die Angabe nur eines Repositorys wie
$LOCATION-docker.pkg.dev/$PROJECT/$REPO funktioniert in Artifact Registry nicht.
cosign ist von Tools wie minisign und
signify inspiriert.
Generierte private Schlüssel werden im PEM-Format gespeichert. Die Schlüssel werden mit einem Passwort verschlüsselt, wobei scrypt als KDF und nacl/secretbox zur Verschlüsselung verwendet werden.
Sie haben einen PEM-Header von ENCRYPTED SIGSTORE PRIVATE KEY:```shell
-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY-----
...
-----END ENCRYPTED SIGSTORE PRIVATE KEY-----
Öffentliche Schlüssel werden auf der Festplatte im PEM-codierten Standard-PKIX-Format mit einem Header von `PUBLIC KEY` gespeichert.```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
-----END PUBLIC KEY-----
cosign speichert Signaturen in einer OCI-Registry und verwendet eine Namenskonvention (Tag auf Basis des sha256 des zu signierenden Objekts), um den Signatur-Index zu lokalisieren.
reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715 hat Signaturen unter reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig
Grob (unter Ignorierung der Ports im Hostnamen): s/:/-/g und s/@/:/g, um den Signatur-Index zu finden.
Siehe Race Conditions für einige Vorbehalte zu dieser Strategie.
Alternative Implementierungen könnten Transparenz-Logs, lokales Dateisystem, eine separate Repository-Registry, eine explizite Referenz auf einen Signatur-Index, eine neue Registry-API, Grafeas usw. verwenden.
cosign funktioniert derzeit nur für Artefakte, die als "Manifeste" in der Registry gespeichert sind.
Der vorgeschlagene Mechanismus ist flexibel genug, um das Signieren beliebiger Dinge zu unterstützen.
cosign unterstützt die Verwendung eines KMS-Anbieters zum Generieren und Signieren von Schlüsseln.
Derzeit unterstützt cosign Hashicorp Vault, AWS KMS, GCP KMS, Azure Key Vault, und wir hoffen, in Zukunft weitere zu unterstützen!
Weitere KMS-Anbieter sind als externe Plugins verfügbar, beispielsweise OVHcloud KMS.
Siehe die KMS-Dokumentation für weitere Details.
Pushen Sie ein Artefakt mithilfe von oras in eine Registry (in diesem Fall cosign selbst!):```shell
$ oras push us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact ./cosign
Uploading f53604826795 cosign
Pushed us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact
Digest: sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
Jetzt signieren! Natürlich mit `cosign`:```shell
$ cosign sign --key cosign.key us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact@sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
Enter password for private key:
Pushing signature to: us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact:sha256-551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef.sig
Schließlich verifizieren Sie cosign erneut mit cosign:```shell
$ cosign verify --key cosign.pub us-central1-docker.pkg.dev/dlorenc-vmtest2/test/artifact@sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef
The following checks were performed on each of these signatures:
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef"},"Type":"cosign container image signature"},"Optional":null}
## FAQ
### Warum nicht Notary v2 verwenden?
Das ist schwer kurz zu beantworten.
Dieser Beitrag enthält einige Vergleiche:
[Notary V2 und Cosign](https://medium.com/@dlorenc/notary-v2-and-cosign-b816658f044d)
Wenn du andere Vergleichsbeiträge findest, sende bitte hier einen PR und wir verlinken sie alle.
### Warum nicht containers/image-Signierung verwenden?
`containers/image`-Signierung ist nah an `cosign` dran, und wir verwenden die Payload-Formate wieder.
`cosign` unterscheidet sich dadurch, dass es mit ECDSA-P256-Schlüsseln statt PGP signiert und
Signaturen in der Registry speichert.
### Warum nicht TUF verwenden?
Ich glaube, dieses Tool ist komplementär zu TUF, und sie können zusammen verwendet werden.
Ich habe es noch nicht ausprobiert, denke aber, dass wir eine Registry auch für die TUF-Speicherung wiederverwenden können.
## Designanforderungen
* Keine externen Dienste für Speicherung, Abfrage oder Abruf von Signaturen
* Wir streben eine möglichst umfassende Registry-Unterstützung an
* Alles sollte über die Registry-API funktionieren
* PGP sollte überhaupt nicht erforderlich sein.
* Benutzer müssen alle Signaturen für ein Image finden können
* Unterzeichner können ein Image nach dem Push signieren
* Mehrere Entitäten können ein Image signieren
* Das Signieren eines Images verändert das Image nicht
* Reine Go-Implementierung
## Zukunftsideen
### Änderungen an der Registry-API
Die Namenskonventionen und Read-Modify-Write-Aktualisierungsmuster, mit denen wir Dinge in
einer Registry speichern, sind ein wenig, nun ja, "hacky".
Ich denke, sie sind die beste (einzige) echte Option, die heute verfügbar ist, aber wenn sich die Registry-API
ändert, können wir diese verbessern.
### Andere Typen
`cosign` kann alles in einer Registry signieren.
Diese Beispiele zeigen das Signieren eines einzelnen Images, aber du könntest auch ein Multi-Plattform-`Index`
oder jeden anderen Artefakttyp signieren.
Das umfasst Helm Charts, Tekton Pipelines und alles andere, das derzeit OCI-Registries
für die Verteilung nutzt.
Das bedeutet auch, dass neue Artefakttypen in eine Registry hochgeladen und signiert werden können.
Ein interessanter Typ zum Speichern und Signieren wären TUF-Repositories.
Ich habe es noch nicht ausprobiert, aber ich bin ziemlich sicher, dass TUF darauf aufbauend implementiert werden könnte.
### Tag-Signierung
`cosign`-Signaturen schützen die Digests von Objekten, die in einer Registry gespeichert sind.
Die optionale `annotations`-Unterstützung (über das `-a`-Flag von `cosign sign`) kann verwendet werden, um zusätzliche
Daten zum Payload hinzuzufügen, das signiert und durch die Signatur geschützt wird.
Ein Anwendungsfall dafür könnte sein, eine Tag->Digest-Zuordnung zu signieren.
Wenn du bestätigen möchtest, dass ein bestimmtes Tag (oder eine Gruppe von Tags) auf einen Digest zeigen soll, kannst du
so etwas ausführen:```shell
$ docker push $IMAGE_URI
The push refers to repository [dlorenc/demo]
994393dc58e7: Pushed
5m: digest: sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 size: 528
$ TAG=sign-me
$ cosign sign --key cosign.key -a tag=$TAG $IMAGE_URI_DIGEST
Enter password for private key:
Pushing signature to: dlorenc/demo:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870.sig
Dann können Sie mithilfe des -a-Flags bei cosign verify überprüfen, dass die tag->digest-Zuordnung ebenfalls in der Signatur abgedeckt ist.
Dieses Beispiel verifiziert, dass der Digest $TAG, der auf (sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870) verweist,
signiert wurde, und außerdem, dass die tag-Annotation den Wert sign-me hat:```shell
$ cosign verify --key cosign.pub -a tag=$TAG $IMAGE_URI | jq .
{
"Critical": {
"Identity": {
"docker-reference": ""
},
"Image": {
"Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36"
},
"Type": "cosign container image signature"
},
"Optional": {
"tag": "sign-me"
}
}
Zeitstempel könnten auch hier hinzugefügt werden, um einen TUF-artigen Schutz vor Freeze-Angriffen zu implementieren.
### Basis-Image/Layer-Signierung
Wie bereits erwähnt, kann `cosign` alles in einer Registry signieren.
Man könnte `cosign` verwenden, um ein Image zu signieren, das als Basis-Image verwendet werden soll,
und diese Provenienz-Metadaten in die resultierenden abgeleiteten Images aufzunehmen.
Dies könnte verwendet werden, um durchzusetzen, dass ein Image aus einem autorisierten Basis-Image erstellt wurde.
Grobe Idee:
* OCI-Manifeste haben eine geordnete Liste von `layer` `Descriptors`, die Annotationen enthalten können.
Siehe [hier](https://github.com/opencontainers/image-spec/blob/master/manifest.md) für die
Spezifikation.
* Ein Basis-Image ist eine geordnete Liste von Layern, an die weitere Layer angehängt werden, sowie ein
anfängliches Konfigurationsobjekt, das verändert wird.
* Ein abgeleitetes Image kann die Konfiguration seines Basis-Images vollständig löschen/zerstören/neu erstellen,
daher würde das Signieren der Konfiguration nur begrenzten Wert bieten.
* Wir können die gesamte Menge der geordneten Basis-Layer signieren und diese Signatur als Annotation an
dem **letzten** Layer im resultierenden Child-Image anbringen.
Dieses Beispiel-Manifest manifest repräsentiert ein Image, das aus einem Basis-Image mit zwei
Layern erstellt wurde.
Ein weiterer Layer wird hinzugefügt, wodurch das endgültige Image entsteht.```json
{
"schemaVersion": 2,
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 7023,
"digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7"
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 32654,
"digest": "sha256:9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0"
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 16724,
"digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b",
"annotations": {
"dev.cosign.signature.baseimage": "Ejy6ipGJjUzMDoQFePWixqPBYF0iSnIvpMWps3mlcYNSEcRRZelL7GzimKXaMjxfhy5bshNGvDT5QoUJ0tqUAg=="
}
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 73109,
"digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
}
],
}
Beachten Sie, dass dies rekursiv für mehrere Zwischen-Basisimages angewendet werden kann.
Cosign-Signaturen (und ihre geschützten Nutzlasten) werden als Artefakte in einer Registry gespeichert. Diese Signaturobjekte können ebenfalls signiert werden, was zu einem neuen, „Gegen-Signatur“-Artefakt führt. Diese „Gegen-Signatur“ schützt die Signatur (oder die Gruppe von Signaturen) und das referenzierte Artefakt, was es ihr ermöglicht, als Attestierung für die Signaturen selbst zu fungieren.
Bevor wir das Signatur-Artefakt signieren, geben wir ihm zunächst einen einprägsamen Namen, damit wir es später wiederfinden können.```shell $ cosign sign --key cosign.key -a sig=original $IMAGE_URI_DIGEST Enter password for private key: Pushing signature to: dlorenc/demo:sha256-97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36.sig $ cosign verify --key cosign.pub dlorenc/demo | jq . { "Critical": { "Identity": { "docker-reference": "" }, "Image": { "Docker-manifest-digest": "97fc222cee7991b5b061d4d4afdb5f3428fcb0c9054e1690313786befa1e4e36" }, "Type": "cosign container image signature" }, "Optional": { "sig": "original" } }
<!-- TODO: https://github.com/sigstore/cosign/issues/2333 -->
Geben Sie dieser Signatur nun einen einprägsamen Namen und signieren Sie sie dann:```shell
$ crane tag $(cosign triangulate $IMAGE_URI) mysignature
2021/02/15 20:22:55 dlorenc/demo:mysignature: digest: sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e size: 556
$ cosign sign --key cosign.key -a sig=counter dlorenc/demo:mysignature
Enter password for private key:
Pushing signature to: dlorenc/demo:sha256-71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e.sig
$ cosign verify --key cosign.pub dlorenc/demo:mysignature
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e"},"Type":"cosign container image signature"},"Optional":{"sig":"counter"}}
Überprüfen Sie schließlich die ursprüngliche Signatur:```shell $ crane manifest dlorenc/demo@sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e { "schemaVersion": 2, "config": { "mediaType": "application/vnd.oci.image.config.v1+json", "size": 233, "digest": "sha256:3b25a088710d03f39be26629d22eb68cd277a01673b9cb461c4c24fbf8c81c89" }, "layers": [ { "mediaType": "application/vnd.oci.descriptor.v1+json", "size": 217, "digest": "sha256:0e79a356609f038089088ec46fd95f4649d04de989487220b1a0adbcc63fadae", "annotations": { "dev.sigstore.cosign/signature": "5uNZKEP9rm8zxAL0VVX7McMmyArzLqtxMTNPjPO2ns+5GJpBeXg+i9ILU+WjmGAKBCqiexTxzLC1/nkOzD4cDA==" } } ] }
## Release-Rhythmus
Wir veröffentlichen Releases nach Bedarf. Patch-Releases werden erstellt, um kleine Fehler zu beheben. Minor-Releases werden regelmäßig veröffentlicht, wenn mehrere Fehler behoben oder Funktionen hinzugefügt wurden. Major-Releases werden veröffentlicht, wenn es Breaking Changes gibt.
## Sicherheit
Falls Sie Sicherheitsprobleme entdecken, beachten Sie bitte sigstores [Sicherheitsprozess](https://github.com/sigstore/.github/blob/main/SECURITY.md)
## Bundle-Dateien in GitHub-Release-Assets
Die GitHub-Release-Assets für `cosign` enthalten Sigstore-Bundle-Dateien, die von [GoReleaser](https://github.com/sigstore/cosign/blob/ac999344eb381ae91455b0a9c5c267e747608d76/.goreleaser.yml#L166) beim Signieren des cosign-Blobs erstellt werden, der zur Überprüfung der Integrität der Release-Binärdateien verwendet wird. Diese Datei wird nicht von cosign selbst verwendet, sondern für Benutzer bereitgestellt, die die [Integrität der Release-Binärdateien überprüfen](https://docs.sigstore.dev/cosign/system_config/installation/#verifying-cosign-with-artifact-key) möchten.