В Kubernetes должен попадать не просто образ с привычным именем вроде app:1.2.3, а проверенный артефакт: с неизменяемым digest, ведомостью состава, подписью и сведениями о сборке.
Для простоты восприятия мы подготовили небольшой список:
- SBOM (Software Bill of Materials) показывает, что находится внутри образа: пакеты, библиотеки, версии и лицензии.
- Подпись через Cosign подтверждает конкретный образ и ожидаемого издателя.
- Attestation и provenance связывают образ с дополнительными доказательствами: ведомостью состава и сведениями о процессе сборки.
- Digest важнее tag, потому что tag можно перезаписать, а digest указывает на конкретное содержимое.
- Kubernetes admission policy превращает проверку в правило допуска: неподписанный или неподтверждённый образ не должен запускаться.
- SBOM и подпись не делают образ автоматически безопасным: они не исправляют CVE, не заменяют защиту CI/CD и не проверяют бизнес-логику приложения.
Задача не в том, чтобы “подписать образ для галочки”, а в том, чтобы Kubernetes запускал только проверенные артефакты, а команда могла быстро доказать, что именно было запущено, кто это выпустил и из чего образ состоит.
Почему это важно для облачной инфраструктуры

В Kubernetes часто уходит привычное имя образа: app:1.2.3, backend:stable или даже app:latest. В обычный день это выглядит удобно: тег понятен разработчикам, его легко указать в Helm chart, манифесте или release notes. Но в момент инцидента одного тега уже недостаточно.
Команде нужно быстро ответить на несколько вопросов: кто собрал образ, из какого кода, какие зависимости попали внутрь, не был ли тег перезаписан и действительно ли в кластере запущен тот артефакт, который проходил релизный процесс. Если ответов нет, расследование превращается в ручной разбор реестра, CI-логов и старых деплоев.
Поэтому защита цепочки поставки строится не вокруг одного инструмента, а вокруг набора доказательств. SBOM показывает состав, подпись подтверждает конкретный артефакт и издателя, attestation добавляет проверяемые сведения о сборке, а политика допуска в Kubernetes делает эти проверки обязательными перед запуском.
Дальше стоит разобрать, какие доказательства нужны перед запуском контейнерного образа и почему одной подписи через Cosign недостаточно.
Что нужно доказать перед запуском контейнерного образа

Контейнерный образ нельзя оценивать одним штампом “можно запускать”: перед запуском нужно понять, что находится внутри, кто выпустил артефакт, не изменилось ли содержимое после публикации и каким процессом образ был собран.
Здесь работает простая аналогия с поставкой оборудования в дата-центр. Недостаточно увидеть знакомое название на коробке. Нужны список комплектующих, пломба целостности и документ о происхождении партии. С контейнерами логика похожая: вместо списка комплектующих — SBOM, вместо пломбы — подпись, вместо документа о происхождении — сведения о сборке.
Чтобы не смешивать эти уровни, доказательства лучше разделить по задачам:
| Механизм | На какой вопрос отвечает | Что проверяет |
| SBOM | Что находится внутри образа? | Пакеты, библиотеки, версии, лицензии |
| Подпись образа | Кто подтвердил этот образ и не менялся ли он? | Целостность артефакта и ожидаемого издателя |
| SBOM attestation | Относится ли ведомость состава именно к этому образу? | Связь SBOM с конкретным артефактом |
| Provenance attestation | Где и каким процессом собран образ? | Репозиторий, сборочный процесс, среду и метаданные сборки |
| Политика допуска | Можно ли запускать это в Kubernetes? | Наличие нужных доказательств и соответствие правилам |
Из этой схемы видно главное: одна подпись не показывает состав образа, а SBOM сам по себе не доказывает, кто выпустил артефакт и не был ли он подменён. Рабочая модель появляется только тогда, когда все доказательства связаны с одним и тем же образом и проверяются перед запуском.
Attestation нужна именно для этой связи. Это подписанное утверждение о свойстве артефакта: например, “для этого образа создан такой SBOM” или “этот образ собран таким процессом”. Provenance — частный и важный вид attestation: сведения о происхождении сборки. Обычно сюда входят репозиторий, commit, сценарий сборки, среда сборки и другие метаданные.
В момент деплоя эти доказательства сходятся в Kubernetes. Политика допуска может разрешить только те образы, у которых есть подпись ожидаемого издателя, подтверждённый SBOM и сведения о происхождении сборки. Если доказательств нет или они не совпадают с правилами, workload не должен запускаться автоматически.
Так команда получает не ручную веру в pipeline, а проверяемую цепочку: при релизе понятно, почему образ разрешён, а при инциденте можно восстановить, какой артефакт был запущен, что входило в его состав и каким процессом он был собран.
Почему digest важнее tag

В прошлой главе мы разобрали, какие доказательства нужны перед запуском образа: состав, подпись, сведения о сборке и политика допуска. Но все эти доказательства имеют смысл только тогда, когда они относятся к конкретному артефакту, а не к удобному имени.
Tag удобен для людей. По строке registry.example.com/app:1.2.3 понятно, что это релиз 1.2.3, такой адрес легко указать в Helm chart, Kubernetes-манифесте или release notes. Но tag — это указатель. Он может быть перезаписан, переиспользован или случайно направлен на другой образ.
Простой сценарий: вчера app:1.2.3 указывал на один образ, а сегодня после повторной сборки или ручной публикации — уже на другой. В манифесте строка выглядит прежней, но содержимое изменилось. Для проверки SBOM, подписи и сведений о сборке это критично: доказательства должны относиться не к названию релиза, а к конкретному содержимому.
Digest решает эту проблему. Это неизменяемый идентификатор образа по содержимому, например registry.example.com/app@sha256:.... Если меняется опубликованный артефакт, меняется и digest. Поэтому app:1.2.3 может быть удобной меткой для человека, а app@sha256:... — точным объектом проверки для системы.
Коротко это можно представить так: tag похож на наклейку “релиз 1.2.3”, а digest — на серийный номер содержимого. Наклейку можно переклеить, серийный номер уже связан с тем, что внутри.
На практике из этого следуют три правила:
- Получать digest после публикации образа в реестр;
- Создавать SBOM, подпись и attestation для image@sha256:..., а не только для имени с tag;
- В Kubernetes-политиках проверять digest и ожидаемого издателя, а не просто знакомое имя образа.
Так проверка “образ app:1.2.3 подписан” превращается в более строгую проверку: “конкретный app@sha256:... подписан ожидаемым издателем”. Это важно и при расследовании инцидента. Команда может точно восстановить, какой артефакт был запущен, какой SBOM к нему относился и какие сведения о сборке были действительны.
Если SBOM создан для одного digest, а в кластер попал другой, ведомость состава уже не доказывает состав запущенного образа. Она описывает соседний артефакт. Поэтому digest становится точкой, вокруг которой связываются все остальные доказательства.
Когда объект доверия зафиксирован, можно переходить к следующему вопросу: кто подтверждает этот артефакт и почему этому подтверждению можно верить. Здесь появляются Cosign и Sigstore.
Cosign и Sigstore: что они добавляют к цепочке доверия

Если говорить коротко, то Cosign и Sigstore добавляют проверяемые доказательства: подпись, связь с ожидаемым издателем и сведения о процессе сборки.
Cosign — это инструмент для подписи и проверки контейнерных образов и других OCI-артефактов. Он может подписать конкретный digest, проверить подпись и создать подписанные утверждения о свойствах артефакта: например, о составе или происхождении сборки.
Sigstore шире. Это экосистема, которая помогает доверять таким подписям без постоянного ручного управления приватными ключами. Упрощённо формула такая: Cosign создаёт и проверяет подпись, а Sigstore помогает понять, кто подписал артефакт и почему этой подписи можно доверять.
Внутри этой схемы есть несколько важных частей:
- Cosign — подпись, проверка и подписанные утверждения об артефакте;
- OIDC/keyless — подпись без долгоживущего приватного ключа, когда идентичность приходит из CI/CD;
- Fulcio — краткоживущий сертификат для подтверждённой идентичности;
- Rekor — журнал прозрачности, где фиксируется факт подписи.
Практический смысл в том, что образ подписывает не абстрактный “кто-то с ключом”, а конкретный процесс. Например, release-сценарий в нужном репозитории и ветке. Поэтому при проверке важно смотреть не только на то, что подпись технически валидна, но и на идентичность подписанта: тот ли это workflow, job или сервисный аккаунт, которому организация доверяет.
Для CI/CD это особенно важно. Если pipeline хранит долгоживущий приватный ключ, его можно украсть и использовать позже. При keyless-подходе постоянного ключа нет: CI/CD-процесс получает подтверждённую идентичность через OIDC, а Fulcio выдаёт краткоживущий сертификат именно для этой сборки.
Для команды это даёт два практических эффекта. Перед деплоем можно автоматически блокировать артефакты, подписанные не тем процессом. А при расследовании видно, какой CI/CD-контур выпустил образ и есть ли запись о подписи в журнале прозрачности Rekor.
Теперь доказательства выглядят связно: digest фиксирует конкретный образ, SBOM описывает его состав, Cosign подписывает артефакт и утверждения, Sigstore помогает проверить доверенную идентичность. Следующий шаг — собрать это в рабочий конвейер: сборка образа, публикация, получение digest, генерация SBOM, подпись, attestation и проверка перед деплоем в Kubernetes.
Как выглядит pipeline: от сборки образа до проверки перед Kubernetes

Что делает CI
Сначала CI собирает образ и публикует его в реестр. После публикации pipeline получает digest опубликованного образа. Это важно: именно реестр фиксирует итоговый артефакт, который потом будет скачивать Kubernetes. Если подписать локальную промежуточную сборку или только tag, доказательства могут относиться не к тому объекту.
Дальше для этого digest создаётся SBOM — ведомость состава ПО. Для этого можно использовать, например, Syft: он анализирует образ и формирует список пакетов, библиотек, версий и лицензий в формате SPDX или CycloneDX.
После этого SBOM не должен оставаться просто файлом среди артефактов CI. Его нужно связать с конкретным digest через attestation, чтобы при проверке было понятно: эта ведомость описывает именно этот образ, а не похожую сборку с тем же tag.
Затем pipeline создаёт сведения о происхождении сборки: из какого репозитория, commit и сценария был собран образ, в какой среде и с какими параметрами. Это не “красивый JSON для отчёта”, а доказательство, которое помогает понять происхождение артефакта.
После этого сам образ подписывается через Cosign. В итоге к одному digest привязаны три слоя доказательств: состав, сведения о сборке и подпись ожидаемого издателя.
Что проверяется перед деплоем
Перед деплоем важно проверить не только сам факт подписи. Валидная подпись полезна только тогда, когда понятно, кто её поставил и почему этому процессу можно доверять.
Проверка должна отвечать на несколько вопросов:
- Подписан ли именно этот digest;
- Совпадает ли подписант с ожидаемой идентичностью;
- Есть ли SBOM, связанный с этим образом;
- Есть ли сведения о происхождении сборки;
- Прошла ли проверка до попадания workload в Kubernetes.
Если пропустить SBOM, команда не сможет быстро анализировать состав образа при уязвимости. Если не создать attestation, ведомость состава останется отдельным файлом, который сложнее связать с конкретным артефактом. Если не проверить идентичность подписанта, валидная подпись ещё не докажет, что образ выпустил нужный release-процесс.
Ручная проверка через cosign verify полезна как тест, но для production её недостаточно. В рабочей схеме проверка должна стать правилом допуска: Kubernetes сам отклоняет Pod, Deployment или Job, если образ не имеет нужной подписи, SBOM или сведений о сборке.
Так pipeline превращается из набора команд в цепочку доверия. CI выпускает артефакт, доказательства связываются с digest, Cosign и Sigstore помогают проверить издателя, а Kubernetes допускает к запуску только те образы, которые соответствуют политике.
Проверка перед деплоем в Kubernetes: admission policy

Pipeline может подготовить все доказательства: digest, SBOM, подпись и сведения о сборке. Но пока их проверяет человек или отдельная команда в CI, это остаётся дисциплиной процесса. Для production-среды важнее другое: Kubernetes должен сам отклонять непроверенные образы до запуска.
Эта точка называется admission. Когда пользователь, CI/CD или GitOps-система отправляет манифест в Kubernetes API, API-сервер может передать запрос контроллеру политик. Контроллер смотрит, какой образ указан в workload, проверяет доказательства в реестре и решает, можно ли создавать ресурс.
Смысл admission policy простой: образ без нужной подписи, без подтверждённого SBOM или без сведений о происхождении сборки не должен запускаться автоматически. Это уже не рекомендация из документации, а правило допуска.
Возможны разные реализации: Sigstore Policy Controller, Kyverno с проверками Cosign, OPA Gatekeeper в связке с внешними проверками или коммерческие admission-контроллеры. Для архитектуры важнее не конкретный продукт, а набор условий, которые проверяются перед запуском:
- Образ должен быть из ожидаемого реестра;
- Проверка должна относиться к digest, а не только к tag;
- Подпись должна быть создана доверенным процессом сборки;
- SBOM должен быть связан с этим образом;
- Provenance attestation должна подтверждать происхождение сборки, если это требуется политикой;
- При несоответствии ресурс должен отклоняться или уходить в отдельный процесс согласования.
Например, если в манифесте указан образ registry.example.com/app@sha256:..., контроллер проверяет, есть ли у этого digest подпись от ожидаемого release-процесса. Затем он может проверить, что для того же digest есть SBOM attestation и сведения о сборке. Если образ подписан другим workflow, не имеет SBOM или относится к другому digest, создание Pod, Deployment, Job или CronJob блокируется.
Отдельная тонкость — использование tag в манифестах. Если команда оставляет app:1.2.3, admission-контроллер должен сам разрешать tag до digest и проверять именно неизменяемый артефакт. Иначе человек видит знакомый релизный tag, а политика может проверять не тот объект, который реально будет скачан и запущен.
После включения admission policy цепочка становится полной. CI собирает образ, публикует его, создаёт SBOM и attestations, подписывает digest, а Kubernetes допускает к запуску только тот артефакт, который соответствует правилам. Дальше остаётся честно разобрать границы этой схемы: какие риски она снижает, а какие всё равно требуют отдельной защиты CI/CD, реестра, зависимостей и самого кластера.
Какие риски закрывают SBOM и подпись, а какие нет

Где связка действительно помогает
Главная польза в том, что команда перестаёт доверять образу только по имени. Вместо app:1.2.3 появляется проверяемый артефакт: digest, состав, подпись и сведения о сборке.
Эту пользу удобно разложить по конкретным рискам: один механизм показывает состав, другой подтверждает целостность, третий связывает доказательства с образом, а политика допуска превращает проверку в обязательное условие запуска.
| Риск | Что помогает | Как снижает риск |
| Уязвимые зависимости | SBOM + сканирование | Можно быстро найти образы с затронутыми пакетами и приоритизировать обновления |
| Подмена образа | Digest + подпись | Если содержимое изменилось, digest и проверка подписи не совпадут с ожидаемым артефактом |
| Неподписанный образ | Политика допуска | Kubernetes блокирует запуск без подписи или с подписью от недоверенной идентичности |
| Подмена SBOM | SBOM attestation | Ведомость состава связана с конкретным digest и подписана |
| Неясное происхождение | Provenance attestation | Видно, каким процессом, из какого репозитория и в какой среде собран образ |
Эти инструменты не “лечат” артефакт, а делают его проверяемым. При релизе и расследовании команда видит не просто имя образа, а конкретный digest, состав, подпись и происхождение сборки.
Но проверяемость артефакта — не то же самое, что полная безопасность. Дальше важно отделить ограничения самого образа от рисков вокруг процесса сборки, реестра и Kubernetes.
Ограничения на уровне самого образа
SBOM показывает, какие пакеты и версии есть в образе, но не обновляет их автоматически. Он также не всегда доказывает, достижима ли конкретная уязвимость в приложении. Поэтому рядом нужны сканирование уязвимостей, приоритизация CVE, обновление зависимостей и политика по критическим находкам.
SBOM также не гарантирует, что зависимость безопасна по смыслу. Он может показать пакет, но не всегда покажет вредоносное поведение, особенно если уязвимость ещё не описана в публичных базах. Для этого нужны review зависимостей, закрепление версий, контроль источников пакетов и проверка репутации.
Подпись тоже не означает, что код внутри корректен. Она подтверждает происхождение и целостность артефакта, но не проверяет бизнес-логику приложения. Ошибки авторизации, небезопасные сценарии обработки данных и баги в логике всё равно остаются зоной code review, тестов, SAST/DAST, threat modeling и безопасной разработки.
Даже если сам образ проверяем, остаётся ещё среда, которая его выпускает, хранит и запускает.
Риски вокруг сборки, реестра и Kubernetes
Здесь важно смотреть не на сам артефакт, а на путь вокруг него:
- CI/CD. Если атакующий получил контроль над разрешённым release-процессом, он может собрать и подписать вредоносный образ “правильной” идентичностью. Нужны защищённые ветки и теги, approvals, минимальные права, изоляция runner’ов и короткоживущие секреты.
- Registry. Подпись помогает обнаружить неподписанный или чужой образ, но не отменяет риски удаления образов, перезаписи тегов и публикации мусора. Нужны минимальные права, immutable tags, аудит действий и отдельные права на удаление.
- Kubernetes. Подписанный образ всё равно может быть опасен в плохо настроенном кластере. Если workload получил лишние права, нет сетевых ограничений или runtime-защиты, нужны Pod Security Standards, network policies, ограничение capabilities, seccomp/AppArmor и мониторинг поведения.
Итоговая формулировка такая: SBOM, Cosign, Sigstore и admission policy повышают доверие к контейнерному артефакту, но не делают весь процесс автоматически безопасным. Они закрывают важную часть цепочки — состав, издателя, происхождение и допуск к запуску. Остальные риски требуют отдельных мер вокруг CI/CD, registry, зависимостей, Kubernetes и самого приложения.
Как читать четыре ключевых риска на практике

После общей карты рисков полезно разобрать несколько сценариев отдельно. Так проще понять, где SBOM и подпись действительно помогают, а где они только дают часть картины.
Уязвимые зависимости
SBOM помогает быстро ответить на вопрос: “Где у нас используется пакет X версии Y?” Это особенно важно во время массовых инцидентов с популярными библиотеками. Без ведомости состава команда часто начинает с ручного поиска по репозиториям, Dockerfile и образам. С SBOM можно быстрее понять, какие образы содержат уязвимый компонент, какие уже запущены в production и какие относятся к критичным сервисам.
Но SBOM не исправляет зависимость сам по себе. Он также не всегда показывает, достижим ли уязвимый код в конкретном приложении. Поэтому рабочий процесс выглядит так: SBOM даёт состав, сканер сопоставляет его с базами уязвимостей, команда приоритизирует исправления, а политика может блокировать деплой образов с критическими уязвимостями выше согласованного порога.
Подмена образа
Подмена образа — это ситуация, когда в кластер попадает не тот артефакт, который команда ожидала. Например, tag app:1.2.3 перезаписали, в реестр опубликовали другой образ или кто-то попытался использовать похожее имя из другого проекта.
Здесь связка digest, подписи и политики допуска работает как жёсткий контроль. Проверяется не знакомая строка в манифесте, а конкретный digest и подпись от ожидаемой идентичности. Если образ подменён, digest изменится. Если образ не подписан нужным процессом, Kubernetes не должен допустить его к запуску.
Неподписанный образ
Неподписанный образ должен считаться недоверенным по умолчанию. Важно формулировать правило именно так: не “если подпись есть, это хорошо”, а “если подписи нет, запуск запрещён”. Иначе подпись остаётся красивой метаданной для дисциплинированных релизов, но не становится реальным барьером.
На практике это означает, что политика допуска должна блокировать Pod, Deployment, CronJob или Job с образом без подписи. То же относится к образу, подписанному не тем процессом: например, тестовым workflow вместо release workflow.
Компрометация CI/CD
Компрометация CI/CD — самый неприятный сценарий, потому что SBOM и подпись дают здесь только частичную защиту. Если атакующий получил доступ к разрешённому release-процессу, он может собрать вредоносный образ, создать SBOM, подписать артефакт и пройти admission-проверку “правильной” идентичностью.
Это не делает подпись бесполезной. Она помогает установить, каким процессом был выпущен артефакт, и сузить расследование. Но для предотвращения нужны отдельные меры: защищённые ветки и теги, обязательные approvals, изолированные runner’ы, минимальные права токенов, запрет произвольных изменений release workflow без ревью, короткоживущие секреты и аудит действий.
Эти четыре сценария показывают главный вывод: SBOM, подпись и admission-проверка усиливают доверие к артефакту, но не заменяют весь контур безопасности. Поэтому внедрение лучше начинать с практического минимума правил, который быстро снижает самые очевидные риски и не требует сразу строить идеальную supply chain-модель.
Минимальный набор правил для внедрения

Правила для артефакта
Сначала нужно сделать сам контейнерный образ проверяемым:
- Не запускать production-образы без digest. Tag можно оставить для удобства людей, но политика должна проверять неизменяемый артефакт.
- Подписывать образ после публикации в registry. Подписывать нужно тот объект, который потом скачает Kubernetes, а не локальную промежуточную сборку.
- Создавать SBOM для каждого релизного образа. Лучше делать это автоматически в CI и связывать ведомость состава с конкретным digest через attestation.
- Проверять идентичность подписанта. Важен не только факт подписи, но и то, кто её поставил: ожидаемый release-процесс, нужный репозиторий, ветка или сервисный аккаунт.
После этих шагов у образа появляется проверяемый “паспорт”: digest, состав, подпись и сведения о происхождении. Но этот паспорт должен не просто лежать рядом с релизом, а реально влиять на запуск.
Правила для допуска и процесса
Второй уровень — сделать проверку обязательной и защитить процесс, который выпускает образ:
- Блокировать неподписанные и неподтверждённые образы на admission-уровне. Если проверка остаётся ручной командой перед релизом, её рано или поздно обойдут.
- Отдельно защищать CI/CD. Подпись артефактов не заменяет безопасность процесса, который эти артефакты создаёт. Нужны защищённые ветки и теги, ревью релизных сценариев, минимальные права, короткоживущие секреты и аудит действий.
Такой минимум закрывает главную дыру: в Kubernetes перестают попадать “просто образы из реестра”. Каждый production-образ должен иметь digest, состав, подпись, сведения о происхождении и пройти автоматическую проверку перед запуском.
Заключение

SBOM, Cosign, Sigstore и политика допуска в Kubernetes нужны не для “галочки безопасности”, а для проверяемости контейнерного артефакта. Команда должна понимать, что именно запущено, из чего собран образ, кто его выпустил и почему этот артефакт был допущен в кластер.
Рабочая схема строится вокруг digest: к нему привязываются ведомость состава, подпись, сведения о сборке и правила допуска. Но эту модель нельзя переоценивать. Она снижает риски подмены образа, неподписанных сборок и слепоты по зависимостям, но не заменяет защиту CI/CD, реестра, Kubernetes и самого приложения.
FAQ
SBOM нужен, если мы уже сканируем образы на уязвимости?
Да. Сканирование помогает найти известные уязвимости, но SBOM полезен как самостоятельная ведомость состава. Его можно хранить, подписывать, передавать клиентам и использовать во время инцидента, когда нужно быстро понять, какие образы содержат конкретную библиотеку или версию пакета.
Подпись Cosign гарантирует, что образ безопасен?
Нет. Подпись подтверждает, что конкретный артефакт был подписан ожидаемой идентичностью и не изменился после подписи. Она не доказывает отсутствие уязвимостей, вредоносной логики, ошибок конфигурации или проблем в бизнес-логике приложения.
Почему нельзя просто подписывать tag?
Потому что tag может быть переиспользован или перезаписан. Надёжнее привязывать подпись, SBOM и attestation к digest: он указывает на конкретное содержимое образа. Если digest изменился, это уже другой объект проверки, даже если tag выглядит так же.
Что делать с образами сторонних поставщиков?
Их тоже нужно проверять: наличие подписи, SBOM, сведений о происхождении, репутацию поставщика и соответствие внутренним политикам. Если поставщик не публикует SBOM или подписи, организация должна отдельно решить, принимает ли она такой риск и какие компенсирующие меры нужны.
Если CI скомпрометирован, подпись бесполезна?
Не совсем. Подпись не предотвращает выпуск вредоносного образа, если атакующий контролирует разрешённый release-процесс. Но она помогает установить происхождение артефакта и применять строгие правила допуска. Для предотвращения такого сценария нужны отдельные меры: защищённые ветки и теги, ревью релизных сценариев, минимальные права, изолированные runner’ы, короткоживущие секреты и аудит действий.


