
cosign v3.1.3
Подписание кода и прозрачность для контейнеров и бинарных файлов
cosign
Подписание OCI-контейнеров (и других артефактов) с помощью Sigstore!
Cosign стремится сделать подписи невидимой инфраструктурой.
Cosign поддерживает:
- "Бесключевое подписание" с центром сертификации Fulcio и журналом прозрачности Rekor публичного блага Sigstore (по умолчанию)
- Аппаратное и KMS-подписание
- Подписание с помощью сгенерированной cosign зашифрованной пары закрытого/открытого ключей
- Подписание, проверка и хранение контейнеров в OCI-реестре.
- Использование собственного PKI
Информация
Cosign разрабатывается в рамках проекта sigstore.
Мы также используем Slack-канал!
Нажмите здесь, чтобы получить пригласительную ссылку.
Установка
Инструкции по установке для Homebrew, Arch, Nix, GitHub Action и Kubernetes см. в документации по установке.
Для Linux и macOS бинарные файлы см. в артефактах релизов GitHub.
🚨 Если вы загружаете релизы cosign из нашего GCS-бакета, пожалуйста, ознакомьтесь с дополнительной информацией в уведомлении об устаревании от 31 июля 2023 года 🚨
Установка для разработчиков
Если у вас установлен Go 1.22+, вы можете настроить среду разработки:```shell $ git clone https://github.com/sigstore/cosign $ cd cosign $ go install ./cmd/cosign $ $(go env GOPATH)/bin/cosign
## Внесение вклада
Если вы заинтересованы во внесении вклада в `cosign`, пожалуйста, прочитайте [документацию по внесению вклада](https://github.com/sigstore/cosign/blob/HEAD/CONTRIBUTING.md).
Будущее развитие Cosign будет сосредоточено на следующем крупном выпуске, который будет основан на
[sigstore-go](https://github.com/sigstore/sigstore-go). Сопровождающие будут сосредоточены на разработке функций в рамках
sigstore-go. Вклад в sigstore-go, особенно в области использования собственных ключей (bring-your-own keys) и подписи, приветствуется.
Пожалуйста, обратитесь к [трекеру проблем](https://github.com/sigstore/sigstore-go/issues), чтобы найти хорошие задачи для начала.
Cosign 2.x — это стабильный релиз, который продолжит получать периодические обновления функций и исправления ошибок. PR,
небольшие по охвату и размеру, скорее всего, будут быстро рассмотрены.
PR, которые значительно изменяют или ломают API, не будут приняты. PR, которые значительны по размеру, но не вносят
разрушающих изменений, могут быть приняты, но будут рассматриваться как менее приоритетные, чем PR в sigstore-go.
## Dockerfile
Вот как установить и использовать cosign внутри Dockerfile с помощью образа 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" ]
Быстрый старт
Здесь показано, как:
- подписать образ контейнера с помощью используемого по умолчанию метода «бесключевой подписи» на основе идентификации (см. документацию для получения дополнительной информации)
- проверить образ контейнера
- изучить более широкие сценарии бесключевого подписания/проверки blob-объектов в кратком руководстве по Sigstore Cosign
Подписание контейнера и сохранение подписи в реестре
Обратите внимание, что всегда следует подписывать образы по их дайджесту (@sha256:...)
а не по тегу (:latest), поскольку в противном случае вы можете подписать не то,
что намеревались подписать!```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 предложит вам пройти аутентификацию через OIDC, где вы войдёте, используя свой адрес электронной почты.
Под капотом cosign запросит сертификат подписи кода у центра сертификации Fulcio.
Субъект сертификата будет соответствовать адресу электронной почты, с которым вы вошли.
Затем cosign сохранит подпись и сертификат в журнале прозрачности Rekor и загрузит подпись в реестр OCI вместе с подписываемым образом.
### Проверка контейнера
Чтобы проверить образ, вам нужно передать ожидаемый субъект сертификата и издателя сертификата с помощью флагов `--certificate-identity` и `--certificate-oidc-issuer`:```
cosign verify $IMAGE --certificate-identity=$IDENTITY --certificate-oidc-issuer=$OIDC_ISSUER
You can also pass in a regex for the certificate identity and issuer flags, --certificate-identity-regexp and --certificate-oidc-issuer-regexp.
Verify a container against a public key
This command returns 0 if at least one cosign formatted signature for the image is found
matching the public key.
See the detailed usage below for information and caveats on other signature formats.
Any valid payloads are printed to stdout, in json format. Note that these signed payloads include the digest of the container image, which is how we can be sure these "detached" signatures cover the correct image.```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}
### Проверка контейнера в изолированной среде
**Примечание:** Этот раздел устарел.
**Примечание:** Большинство процессов проверки требуют периодического запроса ключей службы из репозитория TUF.
Для проверки подписей в изолированной среде с использованием публичного экземпляра вам потребуется получить
[доверенный корневой](https://github.com/sigstore/root-signing/blob/main/targets/trusted_root.json) файл из производственного
репозитория TUF. Содержимое этого файла может изменяться без уведомления. Если вы не используете TUF, вам придётся
создать собственный механизм для поддержания актуальности вашей изолированной копии этого файла.
Cosign может выполнять полностью автономную проверку, проверяя [bundle](https://github.com/sigstore/cosign/blob/HEAD/specs/SIGNATURE_SPEC.md#properties), который обычно распространяется как аннотация к манифесту образа.
Пока эта аннотация присутствует, автономная проверка возможна.
Эта аннотация bundle всегда включается по умолчанию для keyless-подписи, поэтому стандартная функция `cosign sign` будет включать все материалы, необходимые для автономной проверки.
Чтобы проверить образ в изолированной среде, образ и подписи должны быть доступны локально в файловой системе.
Образ можно сохранить локально с помощью `cosign save` (обратите внимание, этот шаг необходимо выполнять при наличии сетевого подключения):```
cosign initialize # This will pull in the latest TUF root
cosign save $IMAGE_NAME --dir ./path/to/dir
Теперь в изолированной от сети среде этот локальный образ можно проверить:```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
Вам нужно передать ожидаемые значения для `$CERT_IDENTITY` и `$CERT_OIDC_ISSUER`, чтобы правильно проверить этот образ.
Если вы подписали с помощью ключевой пары, эта же команда будет работать при условии, что материал открытого ключа присутствует локально:```
cosign verify --key cosign.pub --offline --local-image ./path/to/dir
Подпись и проверка blob на основе идентичности
Используйте бесключевую подпись blob (cosign sign-blob без --key) и проверяйте соответствие ожидаемой личности подписанта:```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"
### Устранение неполадок
Если вы столкнулись с проблемами при использовании Cosign, сначала убедитесь, что используете свежий релиз: проект Cosign активно поддерживает последний релиз, а также последний релиз из серии v2.
#### Частые проблемы и их решения
1. Проверка завершается ошибкой `failed to verify timestamps: threshold not met for verified log entry integrated timestamps: 0 < 1`: возможно, вы проверяете подпись, для которой требуется поддержка временных меток RFC3161
* Обновитесь до последней версии Cosign или
* При использовании Cosign 2.6.x используйте `--use-signed-timestamps`
1. Проверка завершается ошибкой `no signatures found`: возможно, вы проверяете подпись образа, для которой требуется поддержка журнала прозрачности Rekor v2
* Обновитесь до последней версии Cosign
1. Подписание завершается ошибками HTTP: подписание с помощью Cosign зависит от нескольких сервисов Sigstore. Если какой-либо из этих сервисов не работает, полезным обходным решением может быть повторная попытка. Также приветствуется создание issue с описанием конкретных сбоев.
#### Если ваша проблема в чём-то другом
Пожалуйста, создайте [issue](https://github.com/sigstore/cosign/issues/new/choose) или спросите в [slack-канале](#info).
## Работа с другими артефактами
Реестры OCI полезны для хранения не только контейнерных образов!
`Cosign` также включает утилиты для публикации обычных артефактов, включая бинарные файлы, скрипты и конфигурационные файлы, с использованием протокола OCI.
В этом разделе показано, как использовать эти возможности для создания удобной и обратно совместимой системы распространения артефактов, которая хорошо интегрируется с остальной частью Sigstore.
Дополнительную информацию см. в [документации](https://docs.sigstore.dev/cosign/signing/other_types/).
### Blobs
Вы можете опубликовать артефакт с помощью `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
Ваши пользователи могут скачать его по "прямой" ссылке с помощью стандартных инструментов, таких как curl или wget:```shell $ curl -L ttl.sh/v2/$BLOB_NAME/blobs/sha256:$BLOB_SUM > artifact-fetched
Дайджест зашит прямо в URL, так что они могут проверить и его:```shell
$ cat artifact-fetched | shasum -a 256
c69d72c98b55258f9026f984e4656f0e9fd3ef024ea3fac1d7e5c7e6249f1626 -
Вы можете подписать его обычной командой cosign sign и флагами:```shell
$ cosign sign --key cosign.key $BLOB_URI_DIGEST
Enter password for private key:
Pushing signature to: ttl.sh/my-artifact-f42c22e0
Как обычно, обязательно ссылайтесь на любые подписываемые образы по их digest, чтобы случайно не подписать не тот образ!
#### Пакеты Tekton
Пакеты [Tekton](https://tekton.dev) можно загружать и управлять ими в реестре OCI.
Спецификация находится [здесь](https://tekton.dev/docs/pipelines/tekton-bundle-contracts/).
Это означает, что их также можно подписывать и проверять с помощью `cosign`.
Пакеты Tekton в настоящее время можно загружать с помощью [tkn cli](https://github.com/tektoncd/cli), но в будущем мы можем добавить эту поддержку в `cosign`.```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 также могут храниться в реестре OCI, используя эту спецификацию.
Cosign может загружать их с помощью команды 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
Модули [eBPF](https://ebpf.io) также можно хранить в OCI-реестре, используя эту [спецификацию](https://github.com/solo-io/bumblebee/tree/main/spec).
Изображение ниже было создано с помощью инструмента `bee`. Дополнительную информацию можно найти [здесь](https://github.com/solo-io/bumblebee/).
Cosign затем может подписывать эти образы так же, как и любые другие 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
Cosign также имеет встроенную поддержку in-toto аттестаций. Спецификация для них определена здесь.
Вы можете создать и подписать аттестацию из локального файла предиката с помощью следующих команд:```shell $ cosign attest --predicate --key cosign.key $IMAGE_URI_DIGEST
Поддерживаются все стандартные системы управления ключами.
Полезные нагрузки подписываются с использованием спецификации подписи DSSE, определённой [здесь](https://github.com/secure-systems-lab/dsse).
Для проверки:```shell
$ cosign verify-attestation --key cosign.pub $IMAGE_URI
Detailed Usage
See the Usage documentation for more information.
Hardware-based Tokens
See the Hardware Tokens documentation for information on how to use cosign with hardware.
Registry Support
cosign uses go-containerregistry for registry
interactions, which has generally excellent compatibility, but some registries may have quirks.
Today, cosign has been tested and works against the following registries:
- 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
We aim for wide registry support. To sign images in registries which do not yet fully support OCI media types, one may need to use COSIGN_DOCKER_MEDIA_TYPES to fall back to legacy equivalents. For example:```shell
COSIGN_DOCKER_MEDIA_TYPES=1 cosign sign --key cosign.key legacy-registry.example.com/my/image@$DIGEST
Пожалуйста, помогите протестировать и сообщайте об ошибках, если замечаете проблемы!
Инструкции можно найти в [issue по отслеживанию](https://github.com/sigstore/cosign/issues/40).
## Оговорки
### Намеренно отсутствующие функции
`cosign` генерирует только ключи ECDSA-P256 и использует хеши SHA256 как для эфемерной бесключевой подписи, так и для подписи управляемыми ключами.
Ключи хранятся в PEM-кодированном формате PKCS8.
Однако вы можете использовать `cosign` для хранения и получения подписей в любом формате, от любого алгоритма.
### Что, вероятно, следует изменить
#### Форматы полезной нагрузки
`cosign` поддерживает только формат [simple signing](https://www.redhat.com/en/blog/container-image-signing)
от Red Hat для полезной нагрузки.
Выглядит это так:```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
}
}
Примечание: Это может быть сгенерировано для ссылки на образ с помощью cosign generate $IMAGE_URI_DIGEST.
Я готов изменить этот формат на что-то другое, если это имеет смысл. См. https://github.com/notaryproject/nv2/issues/40 для одного из вариантов.
Детали реестра
Подписи cosign хранятся как отдельные объекты в OCI-реестре, имея лишь слабую
ссылку на объект, который они "подписывают".
Это означает, что эта связь невидима для реестра, и подписи не будут удалены
или собраны сборщиком мусора при удалении образа.
Аналогично, их можно легко скопировать из одного окружения в другое, но это не
автоматически.
Несколько подписей хранятся в списке, что, к сожалению, сегодня является состоянием гонки. Чтобы добавить подпись, клиенты выполняют операцию "чтение-добавление-запись", поэтому последняя запись победит в случае конкуренции.
Указание реестра
По умолчанию cosign будет хранить подписи в том же репозитории, что и подписываемый образ.
Чтобы указать другой репозиторий для подписей, вы можете задать переменную окружения COSIGN_REPOSITORY.
Это заменит репозиторий в указанном образе следующим образом:```shell $ export COSIGN_REPOSITORY=gcr.io/my-new-repo $ cosign sign --key cosign.key $IMAGE_URI_DIGEST
Итак, подпись для `gcr.io/dlorenc-vmtest2/demo` будет сохранена в `gcr.io/my-new-repo/demo:sha256-DIGEST.sig`.
Примечание: разные реестры могут ожидать разные форматы для «репозитория».
* Для использования [GCR](https://cloud.google.com/container-registry) достаточно имени реестра
вида `gcr.io/$REPO`, как в примере выше.
* Для использования [Artifact Registry](https://cloud.google.com/artifact-registry)
укажите полное имя образа,
например `$LOCATION-docker.pkg.dev/$PROJECT/$REPO/$STORAGE_IMAGE`, а не просто
репозиторий. Например, ```shell
$ export COSIGN_REPOSITORY=us-docker.pkg.dev/my-new-repo/demo
$ cosign sign --key cosign.key $IMAGE_URI_DIGEST
где sha256-DIGEST будет соответствовать дайджесту для
gcr.io/dlorenc-vmtest2/demo. Указание только репозитория вроде
$LOCATION-docker.pkg.dev/$PROJECT/$REPO не будет работать в Artifact Registry.
Спецификация подписи
cosign создан под влиянием таких инструментов, как minisign и
signify.
Сгенерированные закрытые ключи хранятся в формате PEM. Ключи шифруются паролем с использованием scrypt в качестве KDF и nacl/secretbox для шифрования.
Их PEM-заголовок — ENCRYPTED SIGSTORE PRIVATE KEY:```shell
-----BEGIN ENCRYPTED SIGSTORE PRIVATE KEY-----
...
-----END ENCRYPTED SIGSTORE PRIVATE KEY-----
Открытые ключи хранятся на диске в PEM-кодированном стандартном формате PKIX с заголовком `PUBLIC KEY`.```
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAELigCnlLNKgOglRTx1D7JhI7eRw99
QolE9Jo4QUxnbMy5nUuBL+UZF9qqfm/Dg1BNeHRThHzWh2ki9vAEgWEDOw==
-----END PUBLIC KEY-----
Storage Specification
cosign хранит подписи в OCI-реестре и использует соглашение об именовании (тег на основе sha256 подписываемого объекта) для поиска индекса подписи.
reg.example.com/ubuntu@sha256:703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715 имеет подписи, расположенные по адресу reg.example.com/ubuntu:sha256-703218c0465075f4425e58fac086e09e1de5c340b12976ab9eb8ad26615c3715.sig
Грубо говоря (игнорируя порты в имени хоста): s/:/-/g и s/@/:/g, чтобы найти индекс подписи.
См. Race conditions о некоторых нюансах этой стратегии.
Альтернативные реализации могут использовать transparency logs, локальную файловую систему, отдельный реестр, явную ссылку на индекс подписи, новый API реестра, grafeas и т.д.
Signing subjects
cosign на данный момент работает только с артефактами, хранящимися в реестре в виде «манифестов».
Предлагаемый механизм достаточно гибок, чтобы поддерживать подпись произвольных объектов.
KMS Support
cosign поддерживает использование KMS-провайдера для генерации и подписи ключей.
Прямо сейчас cosign поддерживает Hashicorp Vault, AWS KMS, GCP KMS, Azure Key Vault, и мы надеемся расширить этот список в будущем!
Дополнительные KMS-провайдеры доступны в виде внешних плагинов, например OVHcloud KMS.
Более подробную информацию см. в документации по KMS.
OCI Artifacts
Отправьте артефакт в реестр с помощью oras (в данном случае это сам cosign!):```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
Теперь подпишите это! Используя, конечно, `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
Наконец, снова проверьте cosign с помощью 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
### Почему не Notary v2
На этот вопрос сложно ответить кратко.
В этом посте есть несколько сравнений:
[Notary V2 и Cosign](https://medium.com/@dlorenc/notary-v2-and-cosign-b816658f044d)
Если вы найдёте другие посты со сравнениями, отправьте PR сюда, и мы добавим ссылки на все.
### Почему не подпись через containers/image
Подпись в `containers/image` близка к `cosign`, и мы переиспользуем форматы полезной нагрузки.
`cosign` отличается тем, что подписывает ключами ECDSA-P256 вместо PGP и хранит
подписи в реестре.
### Почему не TUF?
Я считаю, что этот инструмент дополняет TUF, и их можно использовать вместе.
Я ещё не пробовал, но думаю, что мы также можем переиспользовать реестр для хранения TUF.
## Требования к дизайну
* Никаких внешних сервисов для хранения, поиска или получения подписей
* Мы стремимся к максимально возможной поддержке реестров
* Всё должно работать через API реестра
* PGP вообще не должен требоваться.
* Пользователи должны иметь возможность найти все подписи для образа
* Подписанты могут подписать образ после push
* Несколько сущностей могут подписать образ
* Подписание образа не изменяет сам образ
* Реализация на чистом Go
## Идеи на будущее
### Изменения в API реестра
Соглашение об именовании и паттерны обновления read-modify-write, которые мы используем для хранения данных в
реестре, немного, скажем так, «хакерские».
Я думаю, это лучший (и единственный) реальный вариант, доступный сегодня, но если API реестра
изменится, мы сможем это улучшить.
### Другие типы
`cosign` может подписывать что угодно в реестре.
Эти примеры показывают подписание одного образа, но вы также можете подписать многоплатформенный `Index`
или любой другой тип артефакта.
Это включает Helm-чарты, Tekton Pipelines и всё остальное, что сейчас использует OCI-реестры
для распространения.
Это также означает, что новые типы артефактов можно загружать в реестр и подписывать.
Один интересный тип для хранения и подписи — репозитории TUF.
Я ещё не пробовал, но довольно уверен, что TUF можно реализовать поверх этого.
### Подпись тегов
Подписи `cosign` защищают дайджесты объектов, хранящихся в реестре.
Необязательная поддержка `annotations` (через флаг `-a` для `cosign sign`) может использоваться для добавления
дополнительных данных в полезную нагрузку, которая подписывается и защищается подписью.
Один из вариантов использования — подписать сопоставление тег->дайджест.
Если вы хотите засвидетельствовать, что конкретный тег (или набор тегов) должен указывать на дайджест, вы можете
выполнить что-то вроде:```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
Затем вы можете убедиться, что сопоставление тег->digest также покрыто подписью, используя флаг -a для cosign verify.
Этот пример проверяет, что digest $TAG, который указывает на (sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870),
был подписан, а также что аннотация tag имеет значение 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.
### Подпись базового образа/слоя
Опять же, `cosign` может подписывать что угодно в реестре.
Вы можете использовать `cosign` для подписи образа, который предполагается использовать в качестве базового образа,
и включить эти метаданные о происхождении в итоговые производные образы.
Это можно использовать для обеспечения того, чтобы образ был собран из авторизованного базового образа.
Грубая идея:
* OCI-манифесты содержат упорядоченный список `layer` `Descriptor` (дескрипторов слоёв), которые могут содержать аннотации.
Спецификацию см. [здесь](https://github.com/opencontainers/image-spec/blob/master/manifest.md).
* Базовый образ — это упорядоченный список слоёв, к которым добавляются другие слои, а также
исходный объект конфигурации, который мутирует.
* Производный образ может полностью удалить/уничтожить/пересоздать конфигурацию своего базового образа,
поэтому подпись конфигурации дала бы ограниченную ценность.
* Мы можем подписать полный набор упорядоченных базовых слоёв и прикрепить эту подпись как аннотацию к
**последнему** слою в итоговом дочернем образе.
Этот пример манифеста представляет образ, который был собран из базового образа с двумя
слоями.
Дополнительно добавлен ещё один слой, образующий конечный образ.```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"
}
],
}
Обратите внимание, что это можно применять рекурсивно для нескольких промежуточных базовых образов.
Контр-подписание
Подписи Cosign (и их защищённые полезные нагрузки) хранятся в реестре как артефакты. Эти объекты подписей также могут быть подписаны, что приводит к созданию нового артефакта — «контр-подписи». Эта «контр-подпись» защищает подпись (или набор подписей) и связанный артефакт, что позволяет ей служить аттестацией для самих подписей.
Прежде чем мы подпишем артефакт подписи, мы сначала дадим ему запоминающееся имя, чтобы позже его можно было найти.```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 -->
Теперь дайте этой подписи запоминающееся имя, а затем подпишите её:```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"}}
Наконец, проверьте исходную подпись:```shell $ crane manifest dlorenc/demo@sha256:71f70e5d29bde87f988740665257c35b1c6f52dafa20fab4ba16b3b1f4c6ba0e { "schemaVersion": 2, "config": { "mediaType": "application/vnd.oci.image.config.v1+json", "size": 233, "digest": "sha256:3b25a088710d03f39be26629d22eb68cd277a01673b9cb461c4c24fbf8c81c89" }, "layers": [ { "mediaType": "application/vnd.oci.descriptor.v1+json", "size": 217, "digest": "sha256:0e79a356609f038089088ec46fd95f4649d04de989487220b1a0adbcc63fadae", "annotations": { "dev.sigstore.cosign/signature": "5uNZKEP9rm8zxAL0VVX7McMmyArzLqtxMTNPjPO2ns+5GJpBeXg+i9ILU+WjmGAKBCqiexTxzLC1/nkOzD4cDA==" } } ] }
## Release Cadence
Мы выпускаем релизы по мере необходимости. Патч-релизы выпускаются для исправления небольших ошибок. Минорные релизы
выпускаются периодически, когда исправлено несколько ошибок или добавлены функции. Мажорные релизы
будут выпускаться при наличии критически изменяющих функций.
## Security
Если вы обнаружите какие-либо проблемы безопасности, обратитесь к [процедуре безопасности](https://github.com/sigstore/.github/blob/main/SECURITY.md) sigstore.
## Bundle files in GitHub Release Assets
Релизные ассеты GitHub для `cosign` содержат файлы пакетов Sigstore, созданные [GoReleaser](https://github.com/sigstore/cosign/blob/ac999344eb381ae91455b0a9c5c267e747608d76/.goreleaser.yml#L166) при подписании блоба cosign, который используется для проверки целостности бинарных файлов релиза. Этот файл не используется самим cosign, но предоставляется пользователям, которые желают [проверить целостность бинарных файлов релиза](https://docs.sigstore.dev/cosign/system_config/installation/#verifying-cosign-with-artifact-key).