Подпись контейнерного образа позволяет связать неизменяемый digest с подтверждённой личностью или ключом. Проверяющая сторона получает ответ не на вопрос «безопасен ли образ вообще», а на более узкий и практически важный вопрос: «кто подписал именно этот набор байтов и соответствует ли подписант нашей политике доверия».

В 2026 году для OCI-артефактов чаще всего рассматривают два подхода: Cosign из экосистемы Sigstore и Notation — CLI-реализацию спецификаций Notary Project. Оба инструмента умеют размещать подписи рядом с объектом в OCI registry, работать с внешними хранилищами ключей и проверять образ по digest. Но модели идентичности, форматы подписей, управление доверием и степень зависимости от дополнительных сервисов у них различаются.
Краткий ответ: что выбирать
Cosign обычно лучше подходит командам, которым нужна нативная keyless-подпись через OIDC, тесная связь идентичности с CI/CD и экосистема Sigstore. Вместо постоянного закрытого ключа процесс получает краткоживущий сертификат, подтверждающий OIDC-идентичность конкретного workflow, пользователя или workload.
Notation логичнее выглядит в инфраструктуре, где доверие уже строится вокруг X.509, корпоративных центров сертификации, аппаратных модулей и KMS. Его сильная сторона — формализованное разделение trust store и trust policy, а также плагинная модель доступа к ключам.
Выбор не следует сводить к сравнению двух команд CLI. По существу сравниваются две архитектуры доверия:
- OIDC-идентичность, краткоживущий сертификат и, как правило, прозрачный журнал в случае keyless Cosign;
- долгоживущий ключ или сертификат, корпоративная PKI и явно заданная локальная политика в случае типового применения Notation;
- управляемый ключ из KMS — промежуточный вариант, доступный в обеих экосистемах, но реализованный по-разному.
Что именно подписывается
Контейнерный образ следует подписывать по digest, например registry.example.com/team/app@sha256:..., а не полагаться только на тег latest или 1.4. Тег может быть переназначен на другой manifest, тогда как digest однозначно определяет содержимое OCI manifest или index.
IMAGE="registry.example.com/team/app@sha256:<digest>"
cosign sign "$IMAGE"
notation sign --key <key-name> "$IMAGE"
Это не означает, что тег бесполезен: он остаётся удобным именем релиза. Однако перед подписанием CI должен получить digest загруженного объекта и использовать его как окончательную ссылку. Иначе между push и sign возможна подмена или обычная гонка нескольких сборок.
OCI Distribution Specification 1.1 задаёт общий механизм связи артефактов. Подпись публикуется как отдельный manifest, а поле subject указывает на descriptor подписанного объекта. Получить связанные объекты клиент может через Referrers API. Такая схема подходит не только для подписей, но и для других связанных артефактов.
Стандартный способ хранения не делает форматы Cosign и Notation взаимозаменяемыми. Registry способен сохранить оба вида подписи и вернуть их как referrers, но проверяющему клиенту всё равно необходимо понимать конкретный envelope, криптографическую схему и модель доверия.
Cosign: подпись как подтверждение идентичности
Главная особенность Cosign — режим keyless. Процесс аутентифицируется у поддерживаемого OIDC-провайдера и создаёт временную пару ключей. Удостоверяющий центр Sigstore выпускает краткоживущий сертификат, связывающий открытый ключ с утверждениями из OIDC-токена. Закрытый ключ не требуется заранее генерировать, передавать в CI и хранить месяцами.
На практике доверять нужно не абстрактному факту наличия сертификата, а конкретным атрибутам идентичности. При проверке задают ожидаемый OIDC issuer и допустимую identity. Для CI это может быть идентификатор репозитория и workflow, а не имя сотрудника, который однажды настроил pipeline.
cosign verify --certificate-oidc-issuer "<expected-issuer>" --certificate-identity "<expected-identity>" "$IMAGE"
Точные значения issuer и identity зависят от OIDC-провайдера и контекста выпуска сертификата. Их нельзя копировать из случайного примера: сначала следует подписать тестовый образ, изучить сертификат и определить, какие claims стабильны и однозначно описывают доверенный workflow.
Keyless устраняет крупный класс операционных проблем: нет постоянного файла закрытого ключа, который нужно помещать в secret storage, регулярно менять и отзывать после возможной утечки. Но секрет не исчезает полностью — меняется объект защиты. Теперь критичны права на запуск CI, настройки OIDC, правила изменения workflow и доверие к компонентам Sigstore.
Официальная документация Cosign описывает как keyless-подпись после OIDC-аутентификации, так и традиционный режим с локальной парой ключей или URI внешнего KMS. Подписи могут храниться в registry через механизм OCI 1.1 referrers, а связанные объекты просматриваются командой cosign tree.
Когда keyless особенно удобен
- Образы выпускаются автоматизированными workflow, которые способны получать OIDC-токены без постоянных credentials.
- Нужно различать подписи разных репозиториев, веток, workflow или окружений по удостоверенной идентичности.
- Команда не хочет управлять жизненным циклом закрытых ключей для каждого pipeline.
- Проверяющая сторона готова строить policy вокруг OIDC issuer и certificate identity.
- Допустима зависимость от публичной или собственной инфраструктуры Sigstore.
Ограничения keyless
Keyless не равен «подписи без ключа»: криптографическая пара всё равно создаётся, просто закрытый ключ краткоживущий и не является долговременным идентификатором. Доверие переносится на OIDC-провайдера, удостоверяющий центр, корректность claims и, в стандартной модели Sigstore, данные прозрачного журнала.
Для изолированной сети или среды с жёсткими требованиями к внешним зависимостям публичный keyless-процесс может оказаться неудобным. Возможны собственные компоненты Sigstore, однако их эксплуатация превращается в отдельную инфраструктурную задачу: необходимо обслуживать корни доверия, выпуск сертификатов, журнал и процедуры обновления клиентов.
Следует учитывать и жизненный цикл идентичности. Если policy доверяет слишком широкому шаблону, компрометация одного репозитория или workflow может открыть путь к подписи нежелательных образов. Если правило чрезмерно узкое, обычное переименование репозитория или изменение CI-конфигурации остановит проверку. Keyless упрощает ключи, но требует дисциплины при проектировании identity policy.
Cosign с постоянными ключами и KMS
Cosign не ограничивается OIDC. Можно создать локальную пару ключей, подписывать закрытым ключом и проверять открытым:
cosign generate-key-pair
cosign sign --key cosign.key "$IMAGE"
cosign verify --key cosign.pub "$IMAGE"
Такой режим прост для лаборатории или небольшого закрытого контура, но файл закрытого ключа становится долгоживущим секретом. Его нельзя хранить в Git, добавлять в образ runner или передавать между проектами без контроля. Нужны резервирование, ротация, разграничение доступа и понятная процедура отзыва.
Для production предпочтительнее KMS или HSM: операция подписи выполняется внутри защищённого сервиса, а CI получает право вызвать её без извлечения закрытого материала. Cosign принимает URI конкретного провайдера в параметре --key. Синтаксис ссылки на ключ зависит от backend, поэтому его нужно сверять с документацией используемого провайдера.
cosign sign --key "<kms-provider>://<key-reference>" "$IMAGE"
cosign verify --key cosign.pub "$IMAGE"
Проверяющей стороне обычно достаточно экспортированного открытого ключа. Выдавать ей доступ к KMS ради проверки не требуется. Это уменьшает связность систем и позволяет хранить публичный ключ в конфигурации verifier, а закрытый — исключительно в KMS.
Notation: подпись в модели Notary Project
Notation — клиент для подписания и проверки OCI-артефактов по спецификациям Notary Project. Типовая модель основана на X.509-сертификате подписанта и закрытом ключе, который может обслуживаться внешним провайдером. Проверяющая сторона заранее определяет доверенные сертификаты или центры сертификации и описывает, какие identities допустимы для выбранных областей registry.
В отличие от нативного keyless-потока Cosign, ядро модели Notary Project не привязывает подпись к единой публичной OIDC-инфраструктуре. Организация сама управляет PKI либо использует сертификаты и ключи через подключаемого провайдера. Теоретически внешний сервис может автоматизировать краткоживущие ключи и сертификаты, но это не то же самое, что стандартный Sigstore keyless workflow с ожидаемыми OIDC claims.
Такой подход хорошо сочетается с существующими корпоративными процессами:
- центр сертификации уже выпускает сертификаты для code signing;
- ключи создаются в KMS или HSM и не экспортируются;
- есть процедуры выдачи, ротации и отзыва сертификатов;
- аудиторы ожидают увидеть явные корни доверия и правила проверки;
- разные подразделения должны иметь отдельные trust stores и области полномочий.
Форматы подписей: Sigstore bundle против COSE и JWS
Cosign и Notation могут использовать один транспортный слой OCI, но содержимое signature artifact различается.
Формат Cosign
Cosign работает с форматом Sigstore bundle, который объединяет материалы, необходимые для проверки подписи. В keyless-сценарии это позволяет связать криптографическую подпись с сертификатом идентичности и данными, подтверждающими регистрацию события в transparency log. Для подписи постоянным ключом verifier вместо OIDC-идентичности доверяет указанному открытому ключу.
Cosign также поддерживает attestations. Они нужны, когда требуется подписать не только утверждение о принадлежности образа, но и структурированные сведения о происхождении, сборке или другом свойстве. Однако наличие attestation само по себе ничего не гарантирует: verifier должен проверить подписанта и интерпретировать predicate согласно своей policy.
Формат Notation
Спецификации Notary Project предусматривают signature envelope в форматах COSE или JWS. Envelope содержит подписываемый payload и криптографические материалы, а профиль проверки определяет, как валидировать сертификат, подпись, время и связь с целевым OCI-артефактом. Репозиторий спецификаций описывает COSE, JWS, signing scheme, workflow проверки, trust store и trust policy.
Выбор COSE или JWS важен для совместимости конкретных реализаций, но не меняет базовый принцип: хранение подписи в OCI registry и доверие к ней — разные уровни. Registry не обязан разбираться в криптографическом содержимом. Он хранит manifest и blobs, связывает signature artifact с subject и возвращает его клиенту.
Почему подписи не взаимозаменяемы
Нельзя подписать образ Cosign и ожидать, что обычная команда notation verify автоматически применит модель Sigstore. Обратное также неверно. Совпадение digest и использование OCI Referrers обеспечивают совместное хранение, но не единый протокол проверки.
Если в организации есть потребители обоих типов, возможна двойная подпись одного digest. Например, публичный release подписывается keyless через Cosign для внешних пользователей, а внутренний promotion — ключом корпоративного KMS через Notation. Это допустимо, если назначение каждой подписи зафиксировано и pipeline не считает наличие любой подписи достаточным условием доверия.
Trust policy: главное архитектурное различие
Notation делает локальную trust policy одной из центральных частей модели. Политика связывает область registry с доверенными stores, identities и уровнем проверки. В результате правила можно описывать декларативно: для одного namespace доверять корпоративному CA и определённому subject, для другого — отдельному набору сертификатов.
Упрощённо такая policy отвечает на четыре вопроса:
- К каким registry и repository применяется правило?
- Какие trust stores разрешены?
- Какие identities считаются доверенными?
- Какие проверки обязательны и допускаются ли исключения?
Сильная сторона подхода — правила проверки отделены от команды подписи и от самого registry. Недостаток — policy и trust store необходимо согласованно распространять по всем verifier. Устаревший корневой сертификат или несовпадающие области registry приводят к разным результатам проверки одного объекта.
В Cosign базовые проверки часто выражаются параметрами CLI: открытым ключом либо парой ожидаемых значений OIDC issuer и identity. Это удобно в CI, где условия видны непосредственно в pipeline. По мере роста числа repository и подписантов набор аргументов становится сложнее поддерживать, поэтому правила обычно выносят в отдельную конфигурацию или policy engine.
Иными словами, Notation предлагает более явно оформленную trust policy на уровне собственного инструментария. Cosign предлагает гибкую проверку идентичности и хорошо подходит для policy, построенной вокруг claims сертификата Sigstore. Выбор зависит от того, что является первичным объектом доверия: корпоративный сертификат и CA либо OIDC-идентичность автоматизированного процесса.
KMS и плагины: одинаковая цель, разная интеграция
Оба решения позволяют не извлекать закрытый ключ из защищённого backend. Различается способ подключения.
Cosign: URI провайдера
Cosign использует URI, схема которого определяет KMS-провайдера. Интеграция выглядит компактно и удобна для автоматизации: pipeline передаёт ссылку на ключ, а права подписи предоставляются через штатный механизм IAM соответствующего сервиса.
Преимущества:
- небольшое число движущихся частей в типовых поддерживаемых конфигурациях;
- единый интерфейс
--keyдля локального ключа и KMS; - понятная связка с workload identity облачной платформы;
- возможность отдельно экспортировать и распространять открытый ключ.
Ограничение заключается в зависимости от набора backend и возможностей конкретной сборки Cosign. Перед выбором KMS следует проверить поддерживаемые алгоритмы, формат URI, способ получения credentials и доступность операции verify без обращения к закрытому ключу.
Notation: плагинная модель
В Notation операции с ключами могут делегироваться подключаемому плагину. Плагин связывает CLI с KMS, HSM или другим провайдером, не заставляя основную программу реализовывать API каждого сервиса. Спецификации Notary Project определяют требования к расширяемости, чтобы совместимые реализации могли обнаруживать плагин и вызывать поддерживаемые им операции.
Преимущества:
- провайдер может развивать интеграцию независимо от релиза основного CLI;
- проще учитывать особенности корпоративного HSM или специализированного KMS;
- одна модель может охватывать облачные и локальные хранилища ключей;
- границы ответственности между CLI и поставщиком ключевого backend выражены явно.
Но плагин становится частью доверенной вычислительной базы. Нужно контролировать источник бинарного файла, его версию, совместимость, права на файловой системе и процесс обновления. Установка случайного плагина с широкими полномочиями фактически равносильна добавлению к pipeline нового компонента, способного инициировать криптографические операции.
OCI Referrers и совместимость registry
OCI 1.1 стандартизирует модель, в которой подпись или другой связанный артефакт ссылается на исходный manifest через subject. Referrers API позволяет запросить список артефактов, относящихся к конкретному digest. Именно этот уровень даёт Cosign и Notation возможность хранить подписи рядом с образом без модификации самого образа.

Однако заявление registry о поддержке OCI-образов ещё не гарантирует полноценную работу referrers. При оценке совместимости нужно проверить весь путь:
- принимает ли registry manifests с полем
subjectи используемым artifact type; - возвращает ли Referrers API все связанные подписи для digest;
- сохраняются ли связи при копировании образа между registry;
- переносят ли подписи используемые mirroring и promotion-инструменты;
- не удаляет ли garbage collector blobs, которые считает неиспользуемыми;
- сохраняются ли referrers через proxy, cache и репликацию;
- можно ли независимо удалить ошибочную или отозванную подпись;
- поддерживают ли CLI аутентификацию и TLS-настройки конкретного registry.
Проверять нужно не только факт успешной команды sign. Минимальный тест совместимости включает публикацию тестового образа, две независимые подписи, получение списка referrers, проверку обеих подписей, копирование объекта штатным способом и повторную проверку в целевом registry.
Особенно опасен перенос только основного manifest и layers. Digest образа останется тем же, но подписи как отдельные OCI-артефакты не появятся в новом repository. Поэтому процедура promotion должна явно переносить граф связанных объектов либо повторно подписывать digest в целевой зоне доверия.
Для самостоятельного развёртывания и тестирования приватного registry потребуется окружение с административным доступом, например VPS-сервер. Вопросы аутентификации, TLS и очистки образов в таком реестре подробно разобраны в статье о приватном Docker Registry на VDS.
Сравнение Cosign и Notation
| Критерий | Cosign | Notation |
|---|---|---|
| Основная модель | OIDC keyless или постоянный ключ | X.509 и управляемые ключи |
| Нативный keyless OIDC | Ключевой сценарий Sigstore | Не является базовой моделью спецификаций |
| Локальные ключи | Поддерживаются | Поддерживаются через настроенный signing key |
| KMS | URI конкретного провайдера | Плагины провайдеров |
| Формат | Sigstore bundle и связанные форматы Cosign | Signature envelope COSE или JWS |
| Доверие | Открытый ключ либо issuer и certificate identity | Trust store, trust policy и trusted identities |
| Прозрачный журнал | Часть типовой keyless-модели Sigstore | Не является обязательной основой Notary Project |
| Хранение в OCI | OCI 1.1 referrers | OCI signature artifacts и referrers |
| Типичный сценарий | Cloud-native CI/CD и публичные релизы | Корпоративная PKI, KMS и регулируемый контур |
Как выбрать подход для своей инфраструктуры
Выбирайте Cosign keyless, если
- CI-платформа выдаёт OIDC-токены для отдельных workflow;
- важно исключить хранение долгоживущего signing key в pipeline;
- доверие удобно выразить через issuer и identity;
- команда уже использует Sigstore attestations или другие инструменты этой экосистемы;
- потребители образов умеют проверять формат Cosign.
Выбирайте Cosign с KMS, если
- нужна экосистема и интерфейс Cosign, но OIDC keyless недоступен;
- организация требует владеть постоянным ключом;
- подпись должна выполняться управляемым ключом облачного KMS или защищённого хранилища;
- проверку удобно строить вокруг заранее распространённого публичного ключа.
Выбирайте Notation, если
- корпоративная PKI уже является основой code-signing процессов;
- необходимы декларативные trust stores и политики для разных registry scopes;
- ключ должен обслуживаться через официальный или внутренний KMS-плагин;
- потребители или платформенные сервисы стандартизованы на Notary Project;
- важнее интеграция с X.509-процессами, чем OIDC-идентичность CI.
Используйте обе подписи, если
У одного артефакта есть две независимые аудитории. Например, внешние пользователи проверяют keyless-подпись разработчика или release workflow, а внутренний контур требует сертификат корпоративного CA. В таком случае каждый verifier должен искать конкретный тип подписи и конкретного подписанта, а не принимать первую найденную запись.
Практические ошибки при проектировании
Доверять факту наличия любой подписи
Злоумышленник способен подписать чужой публичный образ собственным ключом. Криптографически такая подпись будет корректной, но она не делает подписанта доверенным. Проверка обязана ограничивать ключ, сертификат, issuer, identity или CA.
Подписывать тег без фиксации digest
Между сборкой и подписью тег может указывать уже на другой объект. Pipeline должен получить digest после push и передать одну и ту же digest-ссылку в sign, verify и последующие этапы продвижения.
Считать KMS полной политикой безопасности
KMS защищает закрытый материал, но не гарантирует, что право подписи выдано только нужному workload. Избыточная IAM-роль позволяет легитимно подписать нежелательный образ. Нужно ограничивать вызывающую identity, ключ, окружение и аудит операций.
Не тестировать перенос referrers
Копирование образа не обязательно переносит прикреплённые подписи. Проверка должна выполняться после репликации или promotion в том registry и repository, откуда образ реально будут получать потребители.
Смешивать корни доверия без назначения
Если один repository принимает подписи нескольких CA, OIDC issuer и локальных ключей, следует явно определить роль каждого подписанта. Иначе тестовый ключ или сертификат подрядчика может неожиданно получить те же полномочия, что production release key.
Не планировать ротацию
Для постоянных ключей необходимо заранее решить, сколько времени verifier будет доверять старому ключу, как публикуется новый и как обрабатываются ранее подписанные образы. Для keyless нужно учитывать изменения OIDC claims, адресов репозиториев и конфигурации workflow. Ротация — это изменение policy, а не только создание новой пары ключей.
Итоговый чек-лист
- Определите, кому именно доверяет организация: OIDC-идентичности workflow, открытому ключу или корпоративному CA.
- Выясните, доступна ли инфраструктура Sigstore и допустима ли зависимость от неё.
- Если используется постоянный ключ, выберите KMS или HSM вместо файла в CI.
- Проверьте, поддерживает ли нужный KMS URI Cosign либо совместимый плагин Notation.
- Зафиксируйте формат подписи, который должны понимать все потребители.
- Опишите ограничения identity, issuer, сертификата, ключа и registry scope.
- Подписывайте immutable digest, полученный после загрузки образа.
- Протестируйте OCI Referrers API, удаление, репликацию и копирование подписей.
- Не смешивайте подпись образа со сканированием уязвимостей: это независимые проверки.
- Заранее подготовьте ротацию ключей, сертификатов и trust policy.
Вывод
Cosign и Notation не делятся на «современный» и «устаревший» инструмент. Они оптимизированы под разные центры доверия. Cosign особенно силён там, где личность release-процесса уже выражена через OIDC и нужно отказаться от постоянных ключей. Notation подходит организациям, которые хотят опираться на X.509, корпоративную PKI, KMS-плагины и явно распространяемую trust policy.
OCI 1.1 Referrers сближает инструменты на уровне хранения: подписи связываются с образом по digest и могут находиться в том же registry. Но единый транспорт не создаёт единой модели проверки. Перед внедрением следует выбирать не только CLI, а полный контракт доверия: кто имеет право подписывать, чем подтверждается его identity, где находится ключ, какой формат понимают потребители и переживают ли подписи реальный путь образа между registry.


