Проблема: после deploy есть только финальная запись о выпуске, а вопрос «какой именно output был использован и откуда он взялся?» остаётся без ответа. В такой ситуации легко открыть больше журналов и собрать много деталей, но не получить связанный факт. Цена — неверное решение под давлением: можно откатить не тот output, продолжить спорный выпуск или опубликовать чувствительные данные в попытке доказать, что secret не участвовал в сборке.
Второй риск — принять declaration за расследование. Рядом с deploy может лежать документ с полями source и builder, но без проверки subject, доверенного контекста и сравнения с deploy input он не меняет статус выпуска. Если сразу написать «provenance есть», команда лишает себя права задавать самый важный вопрос: какое звено подтверждено, какое неизвестно и что безопасно делать до завершения проверки.
Начните с узкого диагностического сигнала
Не пытайтесь восстановить всю историю CI. Зафиксируйте один наблюдаемый пробел: deploy input не связан с digest, или digest не связан с declaration, или у declaration нет определённого метода verification. Каждый вариант ведёт к разной следующей проверке. Наблюдение должно быть нейтральным: «связь не найдена» не равно «артефакт вредоносный», а «secret boundary не описана» не равно «секрет утёк». Такая точность сохраняет возможность безопасно остановиться до ложного вывода.
Дальше отделите данные, которые можно назвать, от данных, которые нельзя публиковать. Допустимы synthetic labels, ожидаемый формат digest, идентификатор рассматриваемого звена и владелец проверки. Не нужны секреты, адреса сред, персональные identity, реальные policy, CI log и результаты scanner. В production эти сведения живут в контролируемом контуре и доступны тем, кому это необходимо. Редакционная схема должна помогать поставить вопрос, а не становиться копией чувствительного материала.
| Симптом | Вероятная причина | Проверяемый вопрос | Безопасное действие |
|---|---|---|---|
| Deploy есть, digest неизвестен | вход release не сохранён как ключ сопоставления | какой output был передан в deploy? | приостановить следующий шаг и запросить owner evidence |
| Digest есть, declaration указывает иной subject | statement собран для другого output или перепутан | равны ли subject и рассматриваемый digest? | не использовать declaration как evidence |
| Builder назван, verification не определена | identity смешана с её проверкой | кто и по каким условиям проверяет identity? | завести отдельный verification design |
| Secret boundary описана общо | нет владельца пути передачи | какой этап получает ссылку, а какой не должен видеть значение? | сузить вопрос до одного перехода |
| Все поля есть только в документе | декларация принята за факт среды | какой источник независимо подтвердит каждую связь? | оставить статус requires-verification |
| Нужен срочный rollback | не отделены спорный output и известный кандидат | что уже зависит от deploy input? | выбрать отдельный операционный plan |
Постройте цепочку в прямом, а не обратном порядке
Даже если расследование началось с deploy, карту лучше читать слева направо: source revision → builder identity → secret boundary → artifact digest → attestation declaration → deploy input. Так видно, что каждое звено имеет свой тип evidence. Source и builder отвечают на вопрос о контексте build. Secret boundary отвечает на вопрос о допустимом переходе, но не о содержимом. Digest связывает результат. Declaration описывает claims. Deploy input показывает, какой результат пытались применить. Нельзя заменить одно звено соседним.
Эта последовательность нужна не для бюрократии. Она защищает от диагностической ловушки: когда найден digest, возникает желание считать всё до него и после него понятным. Но digest сам по себе не наблюдал CI; declaration сама по себе не наблюдала deploy. Если все шесть звеньев не имеют общего контракта, их надо пометить как отдельные неизвестности. Такой результат может быть полезнее длинного отчёта, потому что владельцу выпуска ясно, какую проверку заказывать дальше.
Проверьте форму рассуждения локально
Fixture в пакете не заменяет исследование среды, но помогает не перепутать статусы. Он собирает только `synthetic-*` labels, требует один и тот же synthetic digest в artifact и subject declaration, запрещает непомеченный input и не создаёт секрет. В valid branch release всё равно остаётся `manual-review-required`. Это важно: даже идеально собранная учебная карточка не знает, что произошло в CI, и не должна выдавать разрешение на deploy.
node web/scripts/upgrade-2023-06.mjs --verify-fixture
# Проверяем: missing builder, другой subject digest,
# непомеченный input, value-like label и отдельное поле secretValue отклоняются.
# Не проверяем: CI, secret store, подпись, attestation, provenance или deploy.
import {
assembleSyntheticSupplyChain,
runSupplyChainFixture,
} from './upgrade-2023-06.mjs';
const flow = assembleSyntheticSupplyChain({
synthetic: true,
sourceRevision: 'synthetic-source-revision-A',
builderIdentity: 'synthetic-builder-identity-A',
secretLabel: 'synthetic-secret-reference-no-value',
artifactDigest: 'synthetic-digest-artifact-A',
attestationSubjectDigest: 'synthetic-digest-artifact-A',
attestationDeclaration: 'synthetic-attestation-declaration',
});
const report = runSupplyChainFixture();
if (!Object.values(report.assertions).every(Boolean)) throw new Error('fixture failed');
console.log(flow.release.status); // manual-review-required
// Не создаёт secret, certificate, signature, attestation или deploy.
Особенно полезна отрицательная ветка с другим subject digest. Она не утверждает, что настоящий statement поддельный: она показывает, почему несопоставленный statement нельзя использовать в решении. Для реального случая потребуется точный формат данных, метод verification и доказательство, что проверяется тот же предмет. Пока этого нет, release status остаётся не «fail» и не «pass», а «нужен ручной review». Это снижает риск сделать техническое решение на основании неполной семантики.
Маршрут: симптом → причина → проверка → действие
- Симптом. Запишите ровно одну отсутствующую связь: deploy → digest, digest → subject, builder → verification или secret boundary → owner.
- Причина. Проверьте, не заменил ли соседний факт отсутствующее evidence. Например, название CI не доказывает execution, а declaration не доказывает deploy input.
- Проверка. Пройдите таблицу и составьте карточку только с данными, которые допустимо назвать. Локально прогоните fixture, чтобы увидеть все отрицательные ветки контракта.
- Действие. Переведите выпуск в понятный ручной статус, назначьте владельца одного отсутствующего доказательства и выберите наименее рискованный следующий шаг.
- Проверка release. Когда появится real evidence в разрешённом контуре, отдельно сопоставьте его subject с digest и digest с deploy input. Не подменяйте этот шаг текстом в ticket.
- Следующий шаг. После решения сохраните минимальную ссылку на evidence и обновите карту, не копируя секреты или журналы в описание change.
Остановка и rollback — разные действия
Если связь не найдена, первое действие не обязательно rollback. Часто безопаснее не продолжать следующий шаг, сохранить текущий статус и запросить evidence. Rollback нужен, когда уже определён спорный output и есть известный кандидат, к которому можно вернуться без нового скрытого риска. Эти условия нельзя угадывать по наличию attestation. Они зависят от конкретной среды, совместимости и владельцев, поэтому живут в операционном плане, а не в универсальной статье.
Учебный rollback в этом пакете делает гораздо меньше: возвращает шесть synthetic полей исходной карточки, включая subject и declaration, и помечает release no-system-change. Он специально не делает вид, что изменил CI, удалил образ, отозвал credential или исправил production. Это полезная граница для ревью. Она напоминает, что «мы можем откатить» — проверяемое техническое утверждение, а не обязательная строка в конце security документа.
Не выдавайте декларацию за evidence
Подписанная declaration может быть сильным входом, если проверены её подпись, identity, claims, subject и связь с тем output, который идёт в deploy. Но само наличие declaration не доказывает ни provenance, ни использование артефакта, ни отсутствие секрета в output. Это не недостаток формата: так устроена граница утверждения и проверки. Чем точнее команда называет её, тем легче построить контролируемую процедуру без универсальных обещаний.
SSDF помогает обсуждать такие процедуры общим языком, а SLSA v1.0 описывает, какие assurance-утверждения в принципе различаются. Они не заменяют принятие решения в конкретном delivery-контуре. В этой статье нет автоматического gate: есть порядок вопросов, который уменьшает шанс подменить незнание уверенностью. Если реальное evidence невозможно получить безопасно, это тоже результат диагностики: выпуск требует другого решения, а не более громкого statement.
Ограничения и следующий шаг
Здесь нет реальных secrets, tokens, URLs рабочей системы, policies, CVE, CI logs, scanner data, registry или deployment результатов. Fixture строит детерминированный synthetic flow в памяти и не выполняет криптографию. Статья не заявляет, что certificate, signature или attestation создан, проверен или используется. В частности, declaration signing или attestation не доказывает provenance и deployed artifact до самостоятельного сопоставления и проверки в реальной среде.
Следующий шаг — провести короткое review одного release design с владельцем CI и владельцем deploy. Выберите одну missing link из таблицы, договоритесь о границе допустимого evidence и запишите, какой результат переведёт статус из `requires-verification` в следующий технически определённый статус. Не требуйте от первой встречи готового соответствия SLSA. Достаточно, чтобы появилась одна проверяемая связь, которую нельзя спутать с декларацией.
Историческая граница июня 2023
Все ссылки относятся к материалам, доступным к июню 2023: SLSA v1.0 стала стабильной 19 апреля 2023, Cosign v2.0.0 опубликован 24 февраля 2023, NIST SSDF v1.1 — в феврале 2022. Поэтому рассуждение не опирается на будущие CI-интеграции, поздние форматы bundle или современные dashboards. Автор 2023 года пользуется уже доступным словарём supply chain, но не приписывает себе несуществующие проверки.
Проверяемые источники
- SLSA: SLSA v1.0 is now final!, 19 апреля 2023 — официальное объявление фиксирует первый стабильный выпуск SLSA v1.0, доступный к июню 2023. Сам факт выпуска не доказывает соответствие какого-либо pipeline.
- SLSA specification v1.0 — версионная спецификация описывает уровни и рекомендуемые форматы attestation, включая provenance. Сейчас версия помечена retired, но это сохранённая спецификация именно v1.0.
- sigstore/cosign: Release v2.0.0, 24 февраля 2023 — официальный release проекта Sigstore, опубликованный до июня 2023. Наличие инструмента и его формата не означает, что конкретный артефакт был им подписан или проверен.
- NIST SP 800-218 SSDF Version 1.1, Final, 3 февраля 2022 — официальное руководство NIST по практикам безопасной разработки и общему словарю для поставщиков и потребителей. Оно не заменяет evidence конкретного выпуска.