
Firma del codice e trasparenza per contenitori e binari
<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
Firma di container OCI (e altri artefatti) utilizzando [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 mira a rendere le firme **infrastruttura invisibile**.
Cosign supporta:
* "Firma senza chiave" con l'autorità di certificazione Fulcio del bene pubblico Sigstore e il registro di trasparenza Rekor (predefinito)
* Firma hardware e KMS
* Firma con una coppia di chiavi privata/pubblica cifrata generata da cosign
* Firma, verifica e archiviazione di container in un registro OCI.
* Bring-your-own PKI
## Info
`Cosign` è sviluppato come parte del progetto [`sigstore`](https://sigstore.dev).
Utilizziamo anche un [canale slack](https://sigstore.slack.com)!
Clicca [qui](https://join.slack.com/t/sigstore/shared_invite/zt-47srvpyn6-j8Ek5hGBwKN32IjLw8BvYA) per il link di invito.
## Installazione
Per installazioni tramite Homebrew, Arch, Nix, GitHub Action e Kubernetes consulta la [documentazione di installazione](https://docs.sigstore.dev/cosign/system_config/installation/).
Per i binari Linux, macOS e Windows, consulta le [risorse di rilascio su GitHub](https://github.com/sigstore/cosign/releases/latest).
:rotating_light: Se stai scaricando le release di cosign dal nostro bucket GCS - consulta ulteriori informazioni sull'avviso di [deprecazione](https://blog.sigstore.dev/cosign-releases-bucket-deprecation/) del 31 luglio 2023 :rotating_light:
## Installazione per sviluppatori
Se hai Go 1.22+, puoi configurare un ambiente di sviluppo:
```shell
$ git clone https://github.com/sigstore/cosign
$ cd cosign
$ go install ./cmd/cosign
$ $(go env GOPATH)/bin/cosign
```
## Contribuire
Se sei interessato a contribuire a `cosign`, leggi la [documentazione per i contributi](https://github.com/sigstore/cosign/blob/main/CONTRIBUTING.md).
Lo sviluppo futuro di Cosign sarà incentrato sulla prossima major release, che sarà basata su
[sigstore-go](https://github.com/sigstore/sigstore-go). I maintainer si concentreranno sullo sviluppo di funzionalità all'interno
di sigstore-go. I contributi a sigstore-go, in particolare per quanto riguarda bring-your-own keys e la firma, sono apprezzati.
Consulta l'[issue tracker](https://github.com/sigstore/sigstore-go/issues) per le good first issues.
Cosign 2.x è una release stabile e continuerà a ricevere aggiornamenti periodici di funzionalità e correzioni di bug. Le PR
di piccola portata e dimensione hanno maggiori probabilità di essere revisionate rapidamente.
Le PR che modificano o rompono significativamente l'API non saranno accettate. Le PR di dimensioni significative ma che non
introducono breaking changes potrebbero essere accettate, ma saranno considerate a priorità inferiore rispetto alle PR in sigstore-go.
## Dockerfile
Ecco come installare e utilizzare cosign all'interno di un Dockerfile tramite l'immagine ghcr.io/sigstore/cosign/cosign:
```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" ]
```
## Quick Start
Questo mostra come:
* firmare un'immagine container con il metodo predefinito di "keyless signing" basato sull'identità (vedi [la documentazione per maggiori informazioni](https://docs.sigstore.dev/cosign/signing/overview/))
* verificare l'immagine container
* esplorare flussi più ampi di firma/verifica keyless di blob nella [Sigstore Cosign Quickstart](https://docs.sigstore.dev/quickstart/quickstart-cosign/)
### Firmare un container e memorizzare la firma nel registry
Nota che dovresti sempre firmare le immagini in base al loro digest (`@sha256:...`)
piuttosto che a un tag (`:latest`) perché altrimenti potresti firmare qualcosa che
non intendevi firmare!
```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 ti chiederà di autenticarti tramite OIDC, dove accederai con il tuo indirizzo email.
Sotto il cofano, cosign richiederà un certificato di firma del codice all'autorità di certificazione Fulcio.
Il soggetto del certificato corrisponderà all'indirizzo email con cui hai effettuato l'accesso.
Cosign memorizzerà quindi la firma e il certificato nel registro di trasparenza Rekor, e caricherà la firma nel registro OCI insieme all'immagine che stai firmando.
### Verificare un container
Per verificare l'immagine, dovrai passare il soggetto del certificato e l'emittente del certificato previsti tramite i flag `--certificate-identity` e `--certificate-oidc-issuer`:
```
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
```
Puoi anche passare un regex per i flag certificate identity e issuer, `--certificate-identity-regexp` e `--certificate-oidc-issuer-regexp`.
### Verificare un container rispetto a una chiave pubblica
Questo comando restituisce `0` se viene trovata *almeno una* firma in formato `cosign` per l'immagine
corrispondente alla chiave pubblica.
Consulta l'utilizzo dettagliato di seguito per informazioni e avvertenze sugli altri formati di firma.
Eventuali payload validi vengono stampati su stdout, in formato json.
Nota che questi payload firmati includono il digest dell'immagine del container, ed è così che possiamo essere
certi che queste firme "detached" coprano l'immagine corretta.
```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}
```
### Verificare un container in un ambiente air-gapped
**Nota:** Questa sezione è obsoleta.
**Nota:** La maggior parte dei flussi di lavoro di verifica richiede di richiedere periodicamente le chiavi di servizio da un repository TUF.
Per la verifica airgapped delle firme utilizzando l'istanza public-good, sarà necessario recuperare il file
[trusted root](https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json) dal repository
TUF di produzione. Il contenuto di questo file cambierà senza notifica. Non utilizzando TUF, sarà necessario
costruire il proprio meccanismo per mantenere aggiornata la copia airgapped di questo file.
Cosign può eseguire una verifica completamente offline verificando un [bundle](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md#properties) che è tipicamente distribuito come annotazione sul manifest dell'immagine.
Finché questa annotazione è presente, è possibile eseguire la verifica offline.
Questa annotazione bundle è sempre inclusa per impostazione predefinita per la firma keyless, quindi la funzionalità predefinita `cosign sign` includerà tutti i materiali necessari per la verifica offline.
Per verificare un'immagine in un ambiente air-gapped, l'immagine e le firme devono essere disponibili localmente sul filesystem.
Un'immagine può essere salvata localmente utilizzando `cosign save` (nota, questo passaggio deve essere eseguito con una connessione di rete):
```
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
```
Ora, in un ambiente air-gapped, questa immagine locale può essere verificata:
```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
```
Dovrai passare i valori attesi per `$CERT_IDENTITY` e `$CERT_OIDC_ISSUER` per verificare correttamente questa immagine.
Se hai firmato con una coppia di chiavi, lo stesso comando funzionerà, assumendo che il materiale della chiave pubblica sia presente localmente:
```
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
```
### Firma e verifica dei blob basata sull'identità
Utilizza la firma dei blob senza chiave (`cosign sign-blob` senza `--key`) e verifica rispetto all'identità del firmatario prevista:
```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"
```
### Risoluzione dei problemi
Se riscontri problemi con Cosign, assicurati innanzitutto di utilizzare una versione recente: il progetto Cosign supporta attivamente la versione più recente e l'ultima versione della serie v2.
#### Problemi comuni e rimedi
1. La verifica fallisce con `failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1`: potresti star verificando una firma che richiede il supporto dei timestamp RFC3161
* Aggiorna all'ultima versione di Cosign oppure
* Con Cosign 2.6.x, usa `--use-signed-timestamps`
1. La verifica fallisce con `no signatures found`: potresti star verificando la firma di un'immagine che richiede il supporto del log di trasparenza Rekor v2
* Aggiorna all'ultima versione di Cosign
1. La firma fallisce con errori HTTP: la firma con Cosign dipende da più servizi Sigstore. Riprovare in caso di errore può essere una soluzione utile se uno di questi servizi non funziona -- anche segnalare problemi per errori specifici è apprezzato
#### Il mio problema è un altro
Apri una [issue](https://github.com/sigstore/cosign/issues/new/choose) o chiedi nel [canale slack](#info).
## Lavorare con altri artefatti
I registry OCI sono utili per memorizzare non solo immagini container!
`Cosign` include anche alcune utilità per pubblicare artefatti generici, tra cui binari, script e file di configurazione, utilizzando il protocollo OCI.
Questa sezione mostra come sfruttarli per un sistema di distribuzione di artefatti facile da usare e retrocompatibile che si integra bene con il resto di Sigstore.
Consulta [la documentazione](https://docs.sigstore.dev/cosign/signing/other_types/) per maggiori informazioni.
### Blob
Puoi pubblicare un artefatto con `cosign upload blob`:
```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
```
I tuoi utenti possono scaricarlo dall'URL "diretto" con strumenti standard come curl o wget:
```shell
$ curl -L ttl.sh/v2/$BLOB_NAME/blobs/sha256:$BLOB_SUM > artifact-fetched
```
Il digest è incorporato direttamente nell'URL, quindi possono verificarlo anche loro:
```shell
$ cat artifact-fetched | shasum -a 256
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626 -
```
Puoi firmarlo con il normale comando e i flag `cosign sign`:
```shell
$ cosign sign --key cosign.key $BLOB_URI_DIGEST
Enter password for private key:
Pushing signature to: ttl.sh/my-artifact-f42c22e0
```
Come sempre, assicurati di fare riferimento a qualsiasi immagine che firmi tramite il suo digest per essere sicuro di non firmare la cosa sbagliata!
#### Tekton Bundles
I bundle [Tekton](https://tekton.dev) possono essere caricati e gestiti all'interno di un registry OCI.
La specifica è [qui](https://tekton.dev/docs/pipelines/tekton-bundle-contracts/).
Questo significa che possono anche essere firmati e verificati con `cosign`.
Attualmente i Tekton Bundles possono essere caricati con la [tkn cli](https://github.com/tektoncd/cli), ma potremmo aggiungere questo supporto a
`cosign` in futuro.
```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
I Web Assembly Module possono anche essere memorizzati in un registry OCI, utilizzando questa [specifica](https://github.com/solo-io/wasm/tree/master/spec).
Cosign può caricarli utilizzando il comando `cosign wasm upload`:
```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
I moduli [eBPF](https://ebpf.io) possono anche essere archiviati in un registry OCI, utilizzando questa [specifica](https://github.com/solo-io/bumblebee/tree/main/spec).
L'immagine seguente è stata creata utilizzando lo strumento `bee`. Maggiori informazioni sono disponibili [qui](https://github.com/solo-io/bumblebee/)
Cosign può quindi firmare queste immagini come qualsiasi altra immagine OCI.
```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 Attestations
Cosign ha anche un supporto integrato per le attestazioni [in-toto](https://in-toto.io).
La specifica per queste è definita [qui](https://github.com/in-toto/attestation).
Puoi crearne e firmarne una da un file di predicato locale utilizzando i seguenti comandi:
```shell
$ cosign attest --predicate <file> --key cosign.key $IMAGE_URI_DIGEST
```
Tutti i sistemi standard di gestione delle chiavi sono supportati.
I payload sono firmati utilizzando la specifica di firma DSSE, definita [qui](https://github.com/secure-systems-lab/dsse).
Per verificare:
```shell
$ cosign verify-attestation --key cosign.pub $IMAGE_URI
```
## Utilizzo dettagliato
Consultare la [documentazione sull'utilizzo](https://docs.sigstore.dev/cosign/signing/overview/) per ulteriori informazioni.
## Token basati su hardware
Consultare la [documentazione sui token hardware](https://docs.sigstore.dev/cosign/key_management/hardware-based-tokens/) per informazioni su come utilizzare `cosign` con l'hardware.
## Supporto ai registry
`cosign` utilizza [go-containerregistry](https://github.com/google/go-containerregistry) per le interazioni con i registry, che generalmente offre un'ottima compatibilità, ma alcuni registry possono presentare particolarità.
Attualmente, `cosign` è stato testato e funziona con i seguenti registry:
* AWS Elastic Container Registry
* GCP's Artifact Registry and 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
Miriamo a un ampio supporto dei registry. Per `sign` le immagini nei registry che non supportano ancora completamente i [tipi di media OCI](https://github.com/sigstore/cosign/blob/main/specs/SIGNATURE_SPEC.md), potrebbe essere necessario utilizzare `COSIGN_DOCKER_MEDIA_TYPES` per ricorrere a equivalenti legacy. Ad esempio:
```shell
COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image@$DIGEST
```
Per favore, aiuta a testare e segnalare bug se riscontri problemi!
Le istruzioni si trovano nella [tracking issue](https://github.com/sigstore/cosign/issues/40).
## Avvertenze
### Funzionalità intenzionalmente mancanti
`cosign` genera solo chiavi ECDSA-P256 e utilizza hash SHA256, sia per la firma effimera senza chiave che per la firma con chiave gestita.
Le chiavi sono memorizzate in formato PKCS8 codificato PEM.
Tuttavia, puoi usare `cosign` per memorizzare e recuperare firme in qualsiasi formato, da qualsiasi algoritmo.
### Cose che probabilmente dovrebbero cambiare
#### Formati del payload
`cosign` supporta solo il formato [simple signing](https://www.redhat.com/en/blog/container-image-signing) di Red Hat per i payload.
Che assomiglia a:
```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
}
}
```
**Nota:** Questo può essere generato per un riferimento immagine usando `cosign generate $IMAGE_URI_DIGEST`.
Sono felice di cambiare questo formato in qualcos'altro se ha senso.
Vedi https://github.com/notaryproject/notation/issues/40 per una opzione.
#### Dettagli del Registry
Le firme `cosign` sono memorizzate come oggetti separati nel registry OCI, con solo un debole
riferimento all'oggetto che "firmano".
Questo significa che questa relazione è opaca per il registry, e le firme *non* verranno eliminate
o raccolte come garbage quando l'immagine viene eliminata.
Allo stesso modo, **possono** essere facilmente copiate da un ambiente a un altro, ma questo non è
automatico.
Firme multiple sono memorizzate in una lista che sfortunatamente oggi è una race condition.
Per aggiungere una firma, i client orchestrano un'operazione di "read-append-write", quindi l'ultima scrittura
prevarrà in caso di contesa.
##### Specificare il Registry
`cosign` per impostazione predefinita memorizzerà le firme nello stesso repo dell'immagine che sta firmando.
Per specificare un repo diverso per le firme, puoi impostare la variabile d'ambiente `COSIGN_REPOSITORY`.
Questo sostituirà il repo nell'immagine fornita in questo modo:
```shell
$ export COSIGN_REPOSITORY=gcr.io/my-new-repo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
```
Quindi la firma per `gcr.io/dlorenc-vmtest2/demo` sarà memorizzata in `gcr.io/my-new-repo/demo:sha256-DIGEST.sig`.
Nota: registri diversi potrebbero aspettarsi formati diversi per il "repository".
* Per usare [GCR](https://cloud.google.com/container-registry), è sufficiente un nome di registro
come `gcr.io/$REPO`, come nell'esempio sopra.
* Per usare [Artifact Registry](https://cloud.google.com/artifact-registry),
specificare un nome completo dell'immagine come
`$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE`, non solo un
repository. Ad esempio,
```shell
$ export COSIGN_REPOSITORY=us-docker.pkg.dev/my-new-repo/demo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
```
dove `sha256-DIGEST` corrisponderà al digest per
`gcr.io/dlorenc-vmtest2/demo`. Specificare solo un repository come
`$LOCATION-docker.pkg.dev/$PROJECT/$REPO` non funzionerà in Artifact Registry.
## Specifica della firma
`cosign` è ispirato a strumenti come [minisign](https://jedisct1.github.io/minisign/) e
[signify](https://www.openbsd.org/papers/bsdcan-signify.html).
Le chiavi private generate sono memorizzate in formato PEM.
Le chiavi sono crittografate con una password usando scrypt come KDF e nacl/secretbox per la crittografia.
Hanno un'intestazione PEM di `ENCRYPTED SIGSTORE PRIVATE KEY`:
```shell
-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY-----
...
-----END ENCRYPTED SIGSTORE PRIVATE KEY-----
```
Le chiavi pubbliche sono memorizzate su disco in formato PKIX standard codificato PEM con un'intestazione `PUBLIC KEY`.
```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
-----END PUBLIC KEY-----
```
## Specifica di archiviazione
`cosign` memorizza le firme in un registro OCI e utilizza una convenzione di denominazione (tag basato
sullo sha256 di ciò che stiamo firmando) per individuare l'indice delle firme.
<p align="center">
<img src="https://raw.githubusercontent.com/sigstore/cosign/HEAD/images/signatures.dot.svg" />
</p>
`reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715` ha le firme situate in `reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig`
Approssimativamente (ignorando le porte nell'hostname): `s/:/-/g` e `s/@/:/g` per trovare l'indice delle firme.
Vedi [Condizioni di race](#registry-details) per alcune avvertenze relative a questa strategia.
Implementazioni alternative potrebbero utilizzare transparency log, filesystem locale, un registro
repository separato, un riferimento esplicito a un indice delle firme, una nuova API del registro, grafeas, ecc.
### Soggetti della firma
`cosign` funziona oggi solo per artefatti memorizzati come "manifest" nel registro.
Il meccanismo proposto è sufficientemente flessibile da supportare la firma di elementi arbitrari.
### Supporto KMS
`cosign` supporta l'utilizzo di un provider KMS per generare e firmare chiavi.
Attualmente cosign supporta Hashicorp Vault, AWS KMS, GCP KMS, Azure Key Vault e speriamo di supportarne altri in futuro!
Provider KMS aggiuntivi sono disponibili come plugin esterni, come [OVHcloud KMS](https://github.com/ovh/sigstore-kms-ovhcloud).
Vedi la [documentazione KMS](https://docs.sigstore.dev/cosign/key_management/overview/) per maggiori dettagli.
### Artefatti OCI
Esegui il push di un artefatto su un registro utilizzando [oras](https://github.com/deislabs/oras) (in questo caso, `cosign` stesso!):
```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
```
Ora firmalo! Usando `cosign` naturalmente:
```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
```
Infine, verifica `cosign` con `cosign` di nuovo:
```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
### Perché non usare Notary v2
È difficile rispondere brevemente.
Questo post contiene alcuni confronti:
[Notary V2 and Cosign](https://medium.com/@dlorenc/notary-v2-and-cosign-b816658f044d)
Se trovi altri post di confronto, invia una PR qui e li collegheremo tutti.
### Perché non usare la firma di containers/image
La firma di `containers/image` è simile a `cosign`, e riutilizziamo i formati del payload.
`cosign` differisce in quanto firma con chiavi ECDSA-P256 invece che PGP, e memorizza
le firme nel registry.
### Perché non usare TUF?
Ritengo che questo strumento sia complementare a TUF, e possano essere usati insieme.
Non l'ho ancora provato, ma penso che possiamo anche riutilizzare un registry per l'archiviazione TUF.
## Requisiti di progettazione
* Nessun servizio esterno per l'archiviazione, l'interrogazione o il recupero delle firme
* Puntiamo al massimo supporto possibile dei registry
* Tutto dovrebbe funzionare tramite l'API del registry
* PGP non dovrebbe essere affatto richiesto.
* Gli utenti devono essere in grado di trovare tutte le firme per un'immagine
* I firmatari possono firmare un'immagine dopo il push
* Più entità possono firmare un'immagine
* Firmare un'immagine non modifica l'immagine
* Implementazione pure-go
## Idee future
### Modifiche all'API del registry
La convenzione di denominazione e i pattern di aggiornamento read-modify-write che usiamo per memorizzare le cose in
un registry sono un po', beh, "hacky".
Penso che siano la migliore (unica) opzione reale disponibile oggi, ma se l'API del registry
cambia possiamo migliorarle.
### Altri tipi
`cosign` può firmare qualsiasi cosa in un registry.
Questi esempi mostrano la firma di una singola immagine, ma potresti anche firmare un `Index` multi-piattaforma,
o qualsiasi altro tipo di artefatto.
Questo include Helm Charts, Tekton Pipelines e qualsiasi altra cosa che attualmente utilizza i registry OCI
per la distribuzione.
Questo significa anche che nuovi tipi di artefatti possono essere caricati su un registry e firmati.
Un tipo interessante da memorizzare e firmare sarebbero i repository TUF.
Non l'ho ancora provato, ma sono abbastanza certo che TUF potrebbe essere implementato sopra questo.
### Firma dei tag
Le firme di `cosign` proteggono i digest degli oggetti memorizzati in un registry.
Il supporto opzionale delle `annotations` (tramite il flag `-a` di `cosign sign`) può essere usato per aggiungere dati
extra al payload che viene firmato e protetto dalla firma.
Un caso d'uso potrebbe essere la firma di una mappatura tag->digest.
Se desideri attestare che uno specifico tag (o insieme di tag) debba puntare a un digest, puoi
eseguire qualcosa come:
```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
```
Poi puoi verificare che la mappatura tag->digest sia anch'essa coperta nella firma, utilizzando il flag `-a` con `cosign verify`.
Questo esempio verifica che il digest `$TAG` a cui punta (`sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870`)
sia stato firmato, **e anche** che l'annotazione `tag` abbia il valore `sign-me`:
```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"
}
}
```
I timestamp potrebbero anche essere aggiunti qui, per implementare la prevenzione degli attacchi di tipo freeze in stile TUF.
### Firma dell'immagine/del layer di base
Ancora una volta, `cosign` può firmare qualsiasi cosa in un registry.
Potresti usare `cosign` per firmare un'immagine destinata a essere utilizzata come immagine di base,
e includere quei metadati di provenienza nelle immagini derivate risultanti.
Questo potrebbe essere usato per imporre che un'immagine sia stata costruita da un'immagine di base autorizzata.
Idea di massima:
* I manifest OCI hanno una lista ordinata di `Descriptor` di `layer`, che possono contenere annotazioni.
Vedi [qui](https://github.com/opencontainers/image-spec/blob/master/manifest.md) per la
specifica.
* Un'immagine di base è una lista ordinata di layer a cui vengono aggiunti altri layer, oltre a un
oggetto di configurazione iniziale che viene mutato.
* Un'immagine derivata è libera di eliminare/distruggere/ricreare completamente la config dalla sua immagine di base,
quindi firmare la config fornirebbe un valore limitato.
* Possiamo firmare l'intero insieme ordinato dei layer di base, e allegare quella firma come annotazione al
**ultimo** layer nell'immagine figlia risultante.
Questo manifest di esempio rappresenta un'immagine che è stata costruita da un'immagine di base con due
layer.
Un layer aggiuntivo viene aggiunto, formando l'immagine finale.
```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": {
```
---
[Read more](https://github.com/sigstore/cosign)