
Firma del codice e trasparenza per contenitori e binari
Firmare container OCI (e altri artefatti) usando Sigstore!
Cosign punta a rendere le firme un'infrastruttura invisibile.
Cosign supporta:
Cosign è sviluppato come parte del progetto sigstore.
Usiamo anche un canale Slack!
Clicca qui per il link di invito.
Per le installazioni con Homebrew, Arch, Nix, GitHub Action e Kubernetes, consulta la documentazione di installazione.
Per i binari Linux e macOS, consulta le risorse di rilascio GitHub.
🚨 Se stai scaricando release di cosign dal nostro bucket GCS - consulta ulteriori informazioni sull'avviso di deprecazione del 31 luglio 2023 🚨
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 sui contributi](https://github.com/sigstore/cosign/blob/HEAD/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. Sono apprezzati i contributi a sigstore-go, in particolare per quanto riguarda bring-your-own keys e la firma.
Consulta il [issue tracker](https://github.com/sigstore/sigstore-go/issues) per le prime issue adatte.
Cosign 2.x è una release stabile e continuerà a ricevere aggiornamenti periodici di funzionalità e correzioni di bug. Le PR
di piccole dimensioni e ambito limitato hanno maggiori probabilità di essere revisionate rapidamente.
Le PR che modificano in modo significativo o rompono l'API non saranno accettate. Le PR di dimensioni rilevanti ma che non
introducono modifiche breaking possono essere accettate, ma saranno considerate a priorità inferiore rispetto alle PR in sigstore-go.
## Dockerfile
Ecco come installare e usare 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/static
FROM cgr.dev/chainguard/static:latest
COPY --from=cosign-bin /ko-app/cosign /usr/local/bin/cosign
ENTRYPOINT [ "cosign" ]
Questo mostra come:
Nota che dovresti sempre firmare le immagini basandoti sul loro digest (@sha256:...)
piuttosto che su 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.
Dietro le quinte, 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 registry OCI insieme all'immagine che stai firmando.
### Verifica un container
Per verificare l'immagine, dovrai passare il soggetto del certificato atteso e l'emittente del certificato tramite i flag `--certificate-identity` e `--certificate-oidc-issuer`:```
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
Puoi anche passare una regex per i flag relativi all'identità del certificato e all'emittente, --certificate-identity-regexp e --certificate-oidc-issuer-regexp.
Questo comando restituisce 0 se viene trovata almeno una firma in formato cosign per l'immagine che corrisponde 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, che è il modo in cui possiamo essere certi che queste firme "distaccate" coprano l'immagine corretta.```shell $ cosign verify --key cosign.pub $IMAGE_URI:1h The following checks were performed on these signatures:
### Verificare un contenitore in un ambiente air-gapped
**Nota:** questa sezione è obsoleta.
**Nota:** la maggior parte dei flussi di verifica richiede di richiedere periodicamente le chiavi di servizio da un repository TUF.
Per la verifica air-gapped delle firme utilizzando l'istanza public-good, dovrai 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 preavviso. Non utilizzando TUF, dovrai
costruire un tuo meccanismo per mantenere aggiornata la copia air-gapped di questo file.
Cosign può eseguire una verifica completamente offline verificando un [bundle](https://github.com/sigstore/cosign/blob/HEAD/specs/SIGNATURE_SPEC.md#properties) che viene tipicamente distribuito come annotazione sul manifest dell'immagine.
Finché questa annotazione è presente, la verifica offline può essere eseguita.
Questa annotazione bundle è sempre inclusa per impostazione predefinita nella 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 usando `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à, supponendo che il materiale della chiave pubblica sia presente localmente:```
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
Utilizza la firma di blob keyless (cosign sign-blob senza --key) e verifica rispetto all'identità attesa del firmatario:```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 release recente: il progetto Cosign supporta attivamente la release più recente e l'ultima release 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 per i timestamp RFC3161
* Aggiorna alla versione più recente di Cosign oppure
* Con Cosign 2.6.x, usa `--use-signed-timestamps`
1. La verifica fallisce con `no signatures found`: potresti star verificando una firma di un'immagine che richiede il supporto per il log di trasparenza Rekor v2
* Aggiorna alla versione più recente 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 alternativa utile se uno di questi servizi fallisce -- è apprezzata anche l'apertura di issue per i problemi specifici.
#### Il mio problema è un altro
Apri una [issue](https://github.com/sigstore/cosign/issues/new/choose) oppure chiedi nel [canale Slack](#info).
## Lavorare con altri artefatti
I registry OCI sono utili per memorizzare molto più che semplici immagini dei container!
`Cosign` include anche alcune utilità per pubblicare artefatti generici, inclusi binari, script e file di configurazione, utilizzando il protocollo OCI.
Questa sezione mostra come sfruttare questi strumenti per creare un sistema di distribuzione di artefatti facile da usare e retrocompatibile che si integri bene con il resto di Sigstore.
Consulta [la documentazione](https://docs.sigstore.dev/cosign/signing/other_types/) per ulteriori informazioni.
### Blobs
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 "direct" 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, così possono verificarlo anche loro:```shell
$ cat artifact-fetched | shasum -a 256
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626 -
Puoi firmarlo con il normale comando cosign sign e flag:```shell
$ cosign sign --key cosign.key $BLOB_URI_DIGEST
Enter password for private key:
Pushing signature to: ttl.sh/my-artifact-f42c22e0
Come al solito, assicurati di fare riferimento a qualsiasi immagine firmi tramite il digest per essere certo di non firmare la cosa sbagliata!
#### Tekton Bundles
I bundle [Tekton](https://tekton.dev) possono essere caricati e gestiti all'interno di un registro OCI.
La specifica è [qui](https://tekton.dev/docs/pipelines/tekton-bundle-contracts/).
Questo significa che possono anche essere firmati e verificati con `cosign`.
I bundle Tekton possono attualmente essere caricati tramite [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
I moduli Web Assembly possono anche essere archiviati in un registro OCI, utilizzando questa specifica.
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 memorizzati in un registro OCI, utilizzando questa [specifica](https://github.com/solo-io/bumblebee/tree/main/spec).
L'immagine qui sotto è stata creata utilizzando lo strumento `bee`. Ulteriori informazioni sono disponibili [qui](https://github.com/solo-io/bumblebee/)
Cosign può quindi firmare queste immagini come può firmare 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}]
Cosign supporta anche in modo integrato le attestazioni in-toto. La specifica per queste è definita qui.
Puoi creare e firmarne una da un file predicate locale utilizzando i seguenti comandi:```shell $ cosign attest --predicate --key cosign.key $IMAGE_URI_DIGEST
Tutti i sistemi di gestione delle chiavi standard 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
Consulta la documentazione sull'utilizzo per maggiori informazioni.
Consulta la documentazione sui Token Hardware per informazioni su come usare cosign con l'hardware.
cosign utilizza go-containerregistry per le interazioni
con i registry, che ha generalmente un'eccellente compatibilità, ma alcuni registry potrebbero avere peculiarità.
Oggi, cosign è stato testato e funziona con i seguenti registry:
Puntiamo a un'ampia compatibilità con i registry. Per firmare immagini su registry che non supportano ancora completamente i tipi di media OCI, potrebbe essere necessario usare COSIGN_DOCKER_MEDIA_TYPES per ripiegare sugli 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 segnala bug se vedi problemi!
Le istruzioni sono disponibili nella [issue di monitoraggio](https://github.com/sigstore/cosign/issues/40).
## Avvertenze
### Funzionalità volutamente mancanti
`cosign` genera solo chiavi ECDSA-P256 e utilizza hash SHA256, sia per la firma keyless effimera sia per la firma con chiave gestita.
Le chiavi sono memorizzate in formato PEM-encoded PKCS8.
Tuttavia, puoi usare `cosign` per memorizzare e recuperare firme in qualsiasi formato, da qualsiasi algoritmo.
### Cose che probabilmente dovrebbero cambiare
#### Formati dei payload
`cosign` supporta solo il [simple signing](https://www.redhat.com/en/blog/container-image-signing) di Red Hat
come formato per i payload.
Ecco come appare:```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 con qualcos'altro se ha senso. Vedi https://github.com/notaryproject/nv2/issues/40 per un'opzione.
Le firme cosign vengono memorizzate come oggetti separati nel registro OCI, con solo un debole
riferimento all'oggetto che "firmano".
Ciò significa che questa relazione è opaca per il registro e le firme non verranno eliminate
o soggette a garbage collection quando l'immagine viene eliminata.
Allo stesso modo, possono essere facilmente copiate da un ambiente all'altro, ma questo non è
automatico.
Più firme vengono memorizzate in un elenco che oggi è purtroppo una condizione di corsa. Per aggiungere una firma, i client orchestrano un'operazione "read-append-write", quindi l'ultima scrittura vincerà in caso di contesa.
Per impostazione predefinita, cosign memorizza le firme nello stesso repository dell'immagine che sta firmando.
Per specificare un repository diverso per le firme, è possibile impostare la variabile d'ambiente COSIGN_REPOSITORY.
Questo sostituirà il repository nell'immagine fornita in questo modo:```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`.
Nota: diversi registry potrebbero aspettarsi formati diversi per il "repository".
* Per usare [GCR](https://cloud.google.com/container-registry), un nome di registry
come `gcr.io/$REPO` è sufficiente, come nell'esempio precedente.
* Per usare [Artifact Registry](https://cloud.google.com/artifact-registry),
specifica un nome immagine completo come
`$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE`, non solo un
repository. Per esempio, ```shell
$ export COSIGN_REPOSITORY=us-docker.pkg.dev/my-new-repo/demo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
where the sha256-DIGEST will match the digest for
gcr.io/dlorenc-vmtest2/demo. Specifying just a repo like
$LOCATION-docker.pkg.dev/$PROJECT/$REPO will not work in Artifact Registry.
cosign è ispirato a strumenti come minisign e
signify.
Le chiavi private generate sono archiviate in formato PEM. Le chiavi vengono crittografate con una password utilizzando 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 in PEM con un'intestazione `PUBLIC KEY`.```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
-----END PUBLIC KEY-----
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.
reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715 ha le firme situate in reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig
In linea di massima (ignorando le porte nell'hostname): s/:/-/g e s/@/:/g per trovare l'indice delle firme.
Vedi Race conditions per alcune avvertenze su questa strategia.
Implementazioni alternative potrebbero utilizzare log di trasparenza, filesystem locale, un registry di repository separato, un riferimento esplicito a un indice delle firme, una nuova API del registro, grafeas, ecc.
cosign attualmente funziona solo con artefatti memorizzati come "manifests" nel registry. Il meccanismo proposto è abbastanza flessibile da supportare la firma di cose arbitrarie.
cosign supporta l'utilizzo di un provider KMS per generare e firmare le chiavi. Al momento 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.
Consulta la documentazione KMS per maggiori dettagli.
Esegui il push di un artefatto in un registry utilizzando 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 ovviamente `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
Infine, verifica nuovamente cosign con 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
### 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` è vicina a `cosign`, e riutilizziamo i formati di payload.
`cosign` differisce in quanto firma con chiavi ECDSA-P256 invece di PGP, e memorizza le firme nel registry.
### Perché non usare TUF?
Credo che questo strumento sia complementare a TUF, e possano essere usati insieme.
Non ci ho ancora provato, ma penso che possiamo riutilizzare un registry anche per l'archiviazione TUF.
## Requisiti di progettazione
* Nessun servizio esterno per l'archiviazione, la ricerca o il recupero delle firme
* Puntiamo al massimo supporto possibile per i registry
* Tutto dovrebbe funzionare tramite l'API del registry
* PGP non dovrebbe essere affatto richiesto.
* Gli utenti devono poter 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 la modifica
* Implementazione in puro Go
## Idee future
### Modifiche all'API del Registry
Le convenzioni di denominazione e i pattern di aggiornamento read-modify-write che usiamo per archiviare 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 migliorarli.
### 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 usa 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 archiviare e firmare sarebbero i repository TUF.
Non ci ho ancora provato, ma sono abbastanza sicuro che TUF potrebbe essere implementato sopra a questo.
### Firma dei tag
Le firme di `cosign` proteggono i digest degli oggetti archiviati in un registry.
Il supporto opzionale per `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 firmare una mappatura tag->digest.
Se vuoi attestare che un tag specifico (o un insieme di tag) dovrebbe 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 coperta anche dalla firma, usando il flag -a con cosign verify.
Questo esempio verifica che il digest $TAG, che punta a (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"
}
}
Timestamps could also be added here, to implement TUF-style freeze-attack prevention.
Potrebbero essere aggiunti anche timestamp, per implementare la prevenzione degli attacchi di freeze in stile TUF.
### Firma dell'immagine base/livelli
Di nuovo, `cosign` può firmare qualsiasi cosa in un registry.
Si potrebbe usare `cosign` per firmare un'immagine destinata a essere usata come immagine base,
e includere tali metadati di provenienza nelle immagini derivate risultanti.
Questo potrebbe essere usato per imporre che un'immagine sia stata costruita a partire da un'immagine base autorizzata.
Idea di massima:
* I manifest OCI hanno un elenco ordinato di `layer` `Descriptors`, che possono contenere annotazioni.
Vedi [qui](https://github.com/opencontainers/image-spec/blob/master/manifest.md) per la
specifica.
* Un'immagine base è una lista ordinata di livelli a cui vengono aggiunti altri livelli, oltre a un
oggetto di configurazione iniziale che viene mutato.
* Un'immagine derivata è libera di eliminare/distruggere/ricreare completamente la configurazione dalla sua immagine base,
quindi firmare la configurazione fornirebbe un valore limitato.
* Possiamo firmare l'intero insieme dei livelli base ordinati e allegare tale firma come annotazione
all'**ultimo** livello nell'immagine figlia risultante.
Questo esempio di manifest rappresenta un'immagine che è stata costruita da un'immagine base con due
livelli.
Viene aggiunto un ulteriore livello, 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": {
"dev.cosign.signature.baseimage": "Ejy6ipGJjUzMDoQFePWixqPBYF0iSnIvpMWps3mlcYNSEcRRZelL7GzimKXaMjxfhy5bshNGvDT5QoUJ0tqUAg=="
}
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"size": 73109,
"digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736"
}
],
}
Nota che questo potrebbe essere applicato ricorsivamente, per più immagini di base intermedie.
Le firme Cosign (e i loro payload protetti) sono memorizzate come artefatti in un registro. Questi oggetti firma possono anche essere firmati, dando origine a un nuovo artefatto di "contro-firma". Questa "contro-firma" protegge la firma (o l'insieme di firme) e l'artefatto referenziato, il che le consente di agire come un'attestazione delle firme stesse.
Prima di firmare l'artefatto della firma, gli diamo innanzitutto un nome memorabile in modo da poterlo ritrovare in seguito.```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 -->
Ora dai a quella firma un nome memorabile, poi firma quello:```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"}}
Infine, controlla la firma originale:```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==" } } ] }
## Cadenza delle release
Pubbliciamo release quando necessario. Le release patch vengono pubblicate per correggere piccoli bug. Le release minori vengono
pubblicate periodicamente quando vengono corretti più bug o aggiunte funzionalità. Le release major
verranno pubblicate quando sono presenti funzionalità di rottura.
## Sicurezza
Se dovessi scoprire problemi di sicurezza, fai riferimento al [processo
di sicurezza](https://github.com/sigstore/.github/blob/main/SECURITY.md)
## File bundle negli asset delle release GitHub
Gli asset delle release GitHub per `cosign` contengono file bundle Sigstore prodotti da [GoReleaser](https://github.com/sigstore/cosign/blob/ac999344eb381ae91455b0a9c5c267e747608d76/.goreleaser.yml#L166) durante la firma del blob cosign che viene utilizzato per verificare l'integrità dei binari della release. Questo file non è utilizzato da cosign stesso, ma è fornito per gli utenti che desiderano [verificare l'integrità dei binari della release](https://docs.sigstore.dev/cosign/system_config/installation/#verifying-cosign-with-artifact-key).