
Codesignierung und Transparenz für Container und Binärdateien
<p align="center">
<img style="max-width: 100%;width: 300px;" src="https://raw.githubusercontent.com/sigstore/community/main/artwork/cosign/horizontal/color/sigstore_cosign-horizontal-color.svg" alt="Cosign logo"/>
</p>
# cosign
Signieren von OCI-Containern (und anderen Artefakten) mit [Sigstore](https://sigstore.dev/)!
[](https://goreportcard.com/report/github.com/sigstore/cosign)
[](https://github.com/sigstore/cosign/actions/workflows/e2e-tests.yml)
[](https://bestpractices.coreinfrastructure.org/projects/5715)
[](https://securityscorecards.dev/viewer/?uri=github.com/sigstore/cosign)
Cosign hat zum Ziel, Signaturen zu **unsichtbarer Infrastruktur** zu machen.
Cosign unterstützt:
* "Keyless Signing" mit der Sigstore-Gemeinwohl-Zertifizierungsstelle Fulcio und dem Rekor-Transparenzprotokoll (Standard)
* Hardware- und KMS-Signierung
* Signierung mit einem von cosign generierten verschlüsselten privaten/öffentlichen Schlüsselpaar
* Container-Signierung, -Verifizierung und -Speicherung in einer OCI-Registry.
* Bring-your-own-PKI
## Info
`Cosign` wird als Teil des Projekts [`sigstore`](https://sigstore.dev) entwickelt.
Wir nutzen außerdem einen [Slack-Kanal](https://sigstore.slack.com)!
Klicke [hier](https://join.slack.com/t/sigstore/shared_invite/zt-47srvpyn6-j8Ek5hGBwKN32IjLw8BvYA) für den Einladungslink.
## Installation
Für Homebrew-, Arch-, Nix-, GitHub-Action- und Kubernetes-Installationen siehe die [Installationsdokumentation](https://docs.sigstore.dev/cosign/system_config/installation/).
Für Linux-, macOS- und Windows-Binärdateien siehe die [GitHub-Release-Assets](https://github.com/sigstore/cosign/releases/latest).
:rotating_light: Wenn du cosign-Releases aus unserem GCS-Bucket herunterlädst – beachte bitte die weiteren Informationen zum [Deprecation-Hinweis](https://blog.sigstore.dev/cosign-releases-bucket-deprecation/) vom 31. Juli 2023 :rotating_light:
## Entwickler-Installation
Wenn du Go 1.22+ hast, kannst du eine Entwicklungsumgebung einrichten:
```shell
$ git clone https://github.com/sigstore/cosign
$ cd cosign
$ go install ./cmd/cosign
$ $(go env GOPATH)/bin/cosign
```
## Mitwirken
Wenn Sie daran interessiert sind, zu `cosign` beizutragen, lesen Sie bitte die [Beitragsdokumentation](https://github.com/sigstore/cosign/blob/main/CONTRIBUTING.md).
Die zukünftige Cosign-Entwicklung wird sich auf die nächste Hauptversion konzentrieren, die auf
[sigstore-go](https://github.com/sigstore/sigstore-go) basieren wird. Die Maintainer werden sich auf die Funktionsentwicklung innerhalb
von sigstore-go konzentrieren. Beiträge zu sigstore-go, insbesondere rund um Bring-Your-Own-Keys und Signierung, sind willkommen.
Bitte sehen Sie sich den [Issue-Tracker](https://github.com/sigstore/sigstore-go/issues) für gute Einstiegsaufgaben an.
Cosign 2.x ist eine stabile Version und wird weiterhin regelmäßige Funktionsupdates und Fehlerbehebungen erhalten. PRs
mit geringem Umfang und geringer Größe werden am wahrscheinlichsten schnell überprüft.
PRs, die die API erheblich verändern oder brechen, werden nicht akzeptiert. PRs, die erheblich im Umfang sind, aber keine
brechenden Änderungen einführen, können akzeptiert werden, werden jedoch als niedriger priorisiert angesehen als PRs in sigstore-go.
## Dockerfile
Hier erfahren Sie, wie Sie cosign in einem Dockerfile über das Image ghcr.io/sigstore/cosign/cosign installieren und verwenden:
```shell
FROM ghcr.io/sigstore/cosign/cosign:v2.4.1 as cosign-bin
# Source: https://github.com/chainguard-images/images/tree/main/images/static
FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
```
## Schnellstart
Dies zeigt, wie man:
* ein Container-Image mit der standardmäßigen identitätsbasierten „Keyless Signing"-Methode signiert (siehe [die Dokumentation für weitere Informationen](https://docs.sigstore.dev/cosign/signing/overview/))
* das Container-Image verifiziert
* umfassendere Keyless-Blob-Signierungs-/Verifizierungsabläufe im [Sigstore Cosign Quickstart](https://docs.sigstore.dev/quickstart/quickstart-cosign/) erkundet
### Einen Container signieren und die Signatur in der Registry speichern
Beachte, dass du Images immer anhand ihres Digests (`@sha256:...`) signieren solltest
und nicht anhand eines Tags (`:latest`), da du sonst möglicherweise etwas signierst,
was 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 fordert Sie zur Authentifizierung über OIDC auf, wo Sie sich mit Ihrer E-Mail-Adresse anmelden.
Im Hintergrund fordert cosign ein Codesignaturzertifikat von der Fulcio-Zertifizierungsstelle an.
Der Betreff 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.
### Verifizieren eines Containers
Um das Image zu verifizieren, müssen Sie den erwarteten Zertifikatsbetreff und den Zertifikatsaussteller über die Flags `--certificate-identity` und `--certificate-oidc-issuer` übergeben:
```
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
```
Du kannst auch einen Regex für die Zertifikatsidentität und die Issuer-Flags übergeben, `--certificate-identity-regexp` und `--certificate-oidc-issuer-regexp`.
### Einen Container gegen einen öffentlichen Schlüssel verifizieren
Dieser Befehl gibt `0` zurück, wenn *mindestens eine* `cosign`-formatierte Signatur für das Image gefunden wird,
die zum öffentlichen Schlüssel passt.
Siehe die detaillierte Verwendung unten für Informationen und Einschränkungen zu anderen Signaturformaten.
Alle gültigen Payloads werden im json-Format nach stdout ausgegeben.
Beachte, dass diese signierten Payloads den Digest des Container-Images enthalten, wodurch wir sicher sein können,
dass diese "detached"-Signaturen das richtige Image abdecken.
```shell
$ cosign verify --key cosign.pub $IMAGE_URI:1h
The following checks were performed on these signatures:
- The cosign claims were validated
- The signatures were verified against the specified public key
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:87ef60f558bad79beea6425a3b28989f01dd417164150ab3baab98dcbf04def8"},"Type":"cosign container image signature"},"Optional":null}
```
### Einen Container in einer air-gapped Umgebung verifizieren
**Hinweis:** Dieser Abschnitt ist veraltet.
**Hinweis:** Die meisten Verifizierungs-Workflows erfordern das regelmäßige Anfordern von Service-Schlüsseln von einem TUF-Repository.
Für die airgapped Verifizierung von Signaturen unter Verwendung der Public-Good-Instanz müssen Sie die
[trusted root](https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json)-Datei aus dem Produktions-
TUF-Repository abrufen. Der Inhalt dieser Datei wird sich ohne Benachrichtigung ändern. Da Sie TUF nicht verwenden, müssen Sie
Ihren eigenen Mechanismus entwickeln, um Ihre airgapped Kopie dieser Datei auf dem neuesten Stand zu halten.
Cosign kann eine vollständig Offline-Verifizierung durch Verifizierung eines [Bundles](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md#properties) durchführen, das typischerweise als Annotation am Image-Manifest verteilt wird.
Solange diese Annotation vorhanden ist, kann die Offline-Verifizierung durchgeführt werden.
Diese Bundle-Annotation ist standardmäßig immer für Keyless-Signierung enthalten, sodass die Standard-`cosign sign`-Funktionalität alle für die Offline-Verifizierung benötigten Materialien enthält.
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 lokal mit `cosign save` gespeichert werden (beachten Sie, dass dieser Schritt mit einer Netzwerkverbindung durchgeführt werden muss):
```
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
```
Nun kann in einer air-gapped Umgebung dieses lokale Image 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
```
Du musst erwartete Werte für `$CERT_IDENTITY` und `$CERT_OIDC_ISSUER` übergeben, um dieses Image korrekt zu verifizieren.
Wenn du mit einem Schlüsselpaar signiert hast, funktioniert derselbe Befehl, vorausgesetzt, das öffentliche Schlüsselmaterial ist lokal vorhanden:
```
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
```
### Identitätsbasierte Blob-Signierung und -Verifizierung
Verwenden Sie schlüssellose Blob-Signierung (`cosign sign-blob` ohne `--key`) und verifizieren Sie gegen die erwartete Signer-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 bei der Verwendung von Cosign Probleme auftreten, stelle zunächst sicher, dass du eine aktuelle Version verwendest: Das Cosign-Projekt unterstützt aktiv die neueste Version sowie die letzte Version der v2-Serie.
#### Häufige Probleme und Abhilfemaßnahmen
1. Die Verifikation schlägt fehl mit `failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1`: Möglicherweise verifizierst du eine Signatur, die RFC3161-Zeitstempelunterstützung erfordert
* Aktualisiere auf die neueste Cosign-Version oder
* Verwende mit Cosign 2.6.x `--use-signed-timestamps`
1. Die Verifikation schlägt fehl mit `no signatures found`: Möglicherweise verifizierst du eine Image-Signatur, die Unterstützung für das Rekor v2-Transparenzprotokoll erfordert
* Aktualisiere auf die neueste Cosign-Version
1. Die Signierung schlägt fehl mit HTTP-Fehlern: Die Signierung mit Cosign hängt von mehreren Sigstore-Diensten ab. Ein erneuter Versuch bei Fehlschlag kann eine nützliche Problemumgehung sein, falls einer dieser Dienste ausfällt -- das Einreichen von Issues für bestimmte Fehler ist ebenfalls willkommen
#### Mein Problem ist etwas anderes
Bitte öffne ein [Issue](https://github.com/sigstore/cosign/issues/new/choose) oder frage im [Slack-Kanal](#info).
## Arbeiten mit anderen Artefakten
OCI-Registries sind nützlich, um mehr als nur Container-Images zu speichern!
`Cosign` enthält auch einige Dienstprogramme zum Veröffentlichen generischer Artefakte, einschließlich Binärdateien, Skripten und Konfigurationsdateien unter Verwendung des OCI-Protokolls.
Dieser Abschnitt zeigt, wie du diese für ein einfach zu verwendendes, abwärtskompatibles Artefaktverteilungssystem nutzen kannst, das sich gut in den Rest von Sigstore integriert.
Weitere Informationen findest du in [der Dokumentation](https://docs.sigstore.dev/cosign/signing/other_types/).
### Blobs
Du kannst 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 "direct"-URL mit Standardwerkzeugen 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 -
```
Du kannst es mit dem normalen `cosign sign`-Befehl 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 üblich sollten Sie darauf achten, alle Images, die Sie signieren, anhand ihres Digests zu referenzieren, um sicherzustellen, dass Sie nicht das falsche Objekt signieren!
#### Tekton Bundles
[Tekton](https://tekton.dev)-Bundles können in einer OCI-Registry hochgeladen und verwaltet werden.
Die Spezifikation finden Sie [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 der [tkn cli](https://github.com/tektoncd/cli) hochgeladen werden, aber wir könnten diese Unterstützung 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
```
#### WASM
Web Assembly Modules können ebenfalls in einer OCI-Registry gespeichert werden, unter Verwendung dieser [Spezifikation](https://github.com/solo-io/wasm/tree/master/spec).
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, unter Verwendung dieser [Spezifikation](https://github.com/solo-io/bumblebee/tree/main/spec).
Das untenstehende Image wurde mit dem `bee`-Tool erstellt. Weitere Informationen finden sich [hier](https://github.com/solo-io/bumblebee/)
Cosign kann diese Images dann signieren, wie es auch jedes andere OCI-Image signieren kann.
```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}]
```
#### In-Toto-Attestierungen
Cosign bietet außerdem integrierte Unterstützung für [in-toto](https://in-toto.io)-Attestierungen.
Die Spezifikation dafür ist [hier](https://github.com/in-toto/attestation) definiert.
Sie können eine solche aus einer lokalen Prädikatdatei mit den folgenden Befehlen erstellen und signieren:
```shell
$ cosign attest --predicate <file> --key cosign.key $IMAGE_URI_DIGEST
```
Alle gängigen Schlüsselverwaltungssysteme werden unterstützt.
Payloads werden mit der DSSE-Signaturspezifikation signiert, definiert [hier](https://github.com/secure-systems-lab/dsse).
Zur Überprüfung:
```shell
$ cosign verify-attestation --key cosign.pub $IMAGE_URI
```
## Detaillierte Verwendung
Weitere Informationen finden Sie in der [Verwendungsdokumentation](https://docs.sigstore.dev/cosign/signing/overview/).
## Hardware-basierte Token
Informationen zur Verwendung von `cosign` mit Hardware finden Sie in der [Dokumentation zu Hardware-Token](https://docs.sigstore.dev/cosign/key_management/hardware-based-tokens/).
## Registry-Unterstützung
`cosign` verwendet [go-containerregistry](https://github.com/google/go-containerregistry) für Registry-Interaktionen, was im Allgemeinen eine hervorragende Kompatibilität bietet, aber einige Registries können Eigenheiten aufweisen.
Derzeit wurde `cosign` mit den folgenden Registries getestet und funktioniert damit:
* AWS Elastic Container Registry
* GCP's Artifact Registry und Container Registry
* Docker Hub
* Azure Container Registry
* JFrog Artifactory Container Registry
* The CNCF distribution/distribution Registry
* GitLab Container Registry
* GitHub Container Registry
* The CNCF Harbor Registry
* Digital Ocean Container Registry
* Sonatype Nexus Container Registry
* Alibaba Cloud Container Registry
* Red Hat Quay Container Registry 3.6+ / Red Hat quay.io
* Elastic Container Registry
* IBM Cloud Container Registry
* Cloudsmith Container Registry
* The CNCF zot Registry
* OVHcloud Managed Private Registry
Wir streben eine breite Registry-Unterstützung an. Um Images in Registries zu `sign`en, die [OCI-Medientypen](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md) noch nicht vollständig unterstützen, muss man möglicherweise `COSIGN_DOCKER_MEDIA_TYPES` verwenden, um auf Legacy-Ä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 beim Testen 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` generiert nur ECDSA-P256-Schlüssel und verwendet SHA256-Hashes, sowohl für ephemere schlüssellose Signierung als auch für Signierung 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
#### Payload-Formate
`cosign` unterstützt nur Red Hats [simple signing](https://www.redhat.com/en/blog/container-image-signing)
-Format für Payloads.
Das sieht so 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 Image-Referenz mit `cosign generate $IMAGE_URI_DIGEST` generiert werden.
Ich bin gerne bereit, dieses Format in ein anderes zu ändern, wenn es sinnvoll erscheint.
Siehe https://github.com/notaryproject/notation/issues/40 für eine Option.
#### Registry-Details
`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 durch Garbage Collection entfernt werden, wenn das Image 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 heutzutage leider eine Race Condition darstellt.
Um eine Signatur hinzuzufügen, orchestrieren Clients eine „Read-Append-Write"-Operation, sodass bei Konflikten
der letzte Schreibvorgang gewinnt.
##### Registry angeben
`cosign` speichert Signaturen standardmäßig im selben Repo wie das Image, das es signiert.
Um ein anderes Repo für Signaturen anzugeben, können Sie die Umgebungsvariable `COSIGN_REPOSITORY` setzen.
Dadurch wird das Repo im bereitgestellten Image wie folgt ersetzt:
```shell
$ export COSIGN_REPOSITORY=gcr.io/my-new-repo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
```
Die Signatur für `gcr.io/dlorenc-vmtest2/demo` wird also in `gcr.io/my-new-repo/demo:sha256-DIGEST.sig` gespeichert.
Hinweis: Verschiedene Registries erwarten möglicherweise unterschiedliche Formate für das „Repository“.
* Um [GCR](https://cloud.google.com/container-registry) zu verwenden, genügt ein Registry-Name wie `gcr.io/$REPO`, wie im obigen Beispiel.
* Um [Artifact Registry](https://cloud.google.com/artifact-registry) zu verwenden, geben Sie einen vollständigen Image-Namen 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` übereinstimmen wird. Die Angabe nur eines Repos wie
`$LOCATION-docker.pkg.dev/$PROJECT/$REPO` wird in Artifact Registry nicht funktionieren.
## Signatur-Spezifikation
`cosign` ist von Tools wie [minisign](https://jedisct1.github.io/minisign/) und
[signify](https://www.openbsd.org/papers/bsdcan-signify.html) 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-----
```
Public Keys werden auf der Festplatte im PEM-kodierten Standard-PKIX-Format mit einem Header `PUBLIC KEY` gespeichert.
```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
-----END PUBLIC KEY-----
```
## Spezifikation der Speicherung
`cosign` speichert Signaturen in einer OCI-Registry und verwendet eine Namenskonvention (Tag basierend
auf dem sha256 des zu signierenden Objekts) zum Auffinden des Signaturindex.
<p align="center">
<img src="https://raw.githubusercontent.com/sigstore/cosign/HEAD/images/signatures.dot.svg" />
</p>
`reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715` hat Signaturen unter `reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig`
Ungefähr (ohne Ports im Hostnamen): `s/:/-/g` und `s/@/:/g`, um den Signaturindex zu finden.
Siehe [Race conditions](#registry-details) für einige Einschränkungen dieser Strategie.
Alternative Implementierungen könnten Transparenzprotokolle, ein lokales Dateisystem, eine separate Repository-
Registry, eine explizite Referenz auf einen Signaturindex, eine neue Registry-API, grafeas usw. verwenden.
### Signierende Subjekte
`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.
### KMS-Unterstützung
`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!
Zusätzliche KMS-Anbieter sind als externe Plugins verfügbar, wie z. B. [OVHcloud KMS](https://github.com/ovh/sigstore-kms-ovhcloud).
Weitere Details finden Sie in der [KMS-Dokumentation](https://docs.sigstore.dev/cosign/key_management/overview/).
### OCI-Artefakte
Push ein Artefakt in eine Registry mit [oras](https://github.com/deislabs/oras) (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 signiere es! 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
```
Abschließend verifiziere `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:
- The cosign claims were validated
- The claims were present in the transparency log
- The signatures were integrated into the transparency log when the certificate was valid
- The signatures were verified against the specified public key
- The code-signing certificate was verified using trusted certificate authority certificates
{"Critical":{"Identity":{"docker-reference":""},"Image":{"Docker-manifest-digest":"sha256:551e6cce7ed2e5c914998f931b277bc879e675b74843e6f29bc17f3b5f692bef"},"Type":"cosign container image signature"},"Optional":null}
```
## FAQ
### Warum nicht Notary v2 verwenden
Das lässt sich nur schwer kurz beantworten.
Dieser Beitrag enthält einige Vergleiche:
[Notary V2 und Cosign](https://medium.com/@dlorenc/notary-v2-and-cosign-b816658f044d)
Wenn du weitere Vergleichsbeiträge findest, sende bitte einen PR hier ein und wir werden sie alle verlinken.
### Warum nicht containers/image-Signierung verwenden
Die `containers/image`-Signierung ist nahe an `cosign`, und wir verwenden dieselben Payload-Formate wieder.
`cosign` unterscheidet sich darin, 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, aber ich denke, wir können auch eine Registry für die TUF-Speicherung wiederverwenden.
## Design-Anforderungen
* Keine externen Dienste für Signaturspeicherung, -abfrage oder -abruf
* Wir streben nach möglichst breiter Registry-Unterstützung
* 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
## Zukünftige Ideen
### Änderungen an der Registry-API
Die Namenskonvention und die Read-Modify-Write-Aktualisierungsmuster, die wir verwenden, um Dinge in
einer Registry zu 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 einen Multi-Plattform-`Index`
oder jede andere Art von Artefakt signieren.
Dazu gehören Helm Charts, Tekton Pipelines und alles andere, das derzeit OCI-Registries
zur 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 mir ziemlich sicher, dass TUF auf dieser Basis 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 für `cosign sign`) kann verwendet werden, um zusätzliche
Daten zur Payload hinzuzufügen, die signiert und durch die Signatur geschützt werden.
Ein Anwendungsfall hierfür könnte das Signieren einer Tag->Digest-Zuordnung sein.
Wenn du bezeugen möchtest, dass ein bestimmter Tag (oder eine Reihe von Tags) auf einen Digest zeigen soll, kannst du
etwas wie Folgendes 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 überprüfen, dass die Tag->Digest-Zuordnung ebenfalls in der Signatur enthalten ist, indem Sie das `-a`-Flag an `cosign verify` verwenden.
Dieses Beispiel überprüft, 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 hier ebenfalls hinzugefügt werden, um eine TUF-artige Freeze-Attack-Prävention zu implementieren.
### Base Image/Layer Signing
Auch hier kann `cosign` alles in einer Registry signieren.
Du könntest `cosign` verwenden, um ein Image zu signieren, das als Basis-Image verwendet werden soll,
und diese Provenienz-Metadaten in die daraus abgeleiteten Images aufnehmen.
Dies könnte genutzt werden, um zu erzwingen, dass ein Image aus einem autorisierten Basis-Image gebaut 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.
---
[Read more](https://github.com/sigstore/cosign)