Как защитить свой CI/CD pipeline

Tue Aug 25 2026

Как защитить свой CI/CD pipeline

Но 14 марта 2025 года злоумышленник перенаправил каждый version tag инцидента tj-actions/changed-files — от v1 до v45.0.7 — на вредоносный коммит. Этот action использовался более чем в 23 000 репозиториев. Его payload сканировал память runner и выводил секреты в workflow logs.

Сканирование CVE не обнаружит вредоносные пакеты с нулевым количеством CVE. Такие пакеты могут скомпрометировать системы, которые собирают, тестируют или выпускают ваше программное обеспечение. Считать YAML безвредной конфигурацией — логическая ошибка. Pipeline — это production-инфраструктура, независимо от того, считает ли ваша организация свой YAML критичным для безопасности.

Краткий ответ: закрепляйте third-party actions, задавайте явные permissions, заменяйте долгоживущие cloud secrets на OIDC с узким доверием, блокируйте зависимости и создавайте SBOM, затем подписывайте и проверяйте release artifacts.

Поэтому в этом руководстве NIST Secure Software Development Framework (SSDF) используется как карта на основе рисков. Руководство отслеживает доверие от source к build, затем к artifact и deployment, после чего предлагает модель ответственности и порядок из пяти контролей.

Security controls mapped across a CI/CD pipeline from source to deployment.

В этой статье

Злоумышленники могут проникнуть до появления CVE

Начните не с отчета CVE. Он сообщает об известных уязвимостях компонентов. Он не может подтвердить доверие к вашему workflow, runner, credentials или release process.

Я бы не использовал отчет Phoenix Security о 59 кампаниях и 657 вредоносных пакетах в качестве прогноза. Его полезный вывод более узок: вредоносные inputs могут не иметь известных CVE.

Предположите, что злоумышленник может изменить upstream action, отправить код из fork, скомпрометировать publisher зависимости или изменить CI-конфигурацию. Остановите этот код до того, как он получит следующие credentials или release privilege.

Три маршрута требуют отдельного рассмотрения:

  • Pipeline injection: код workflow, reusable workflows, action references, UI configuration или environment variables заставляют runner выполнять инструкции, контролируемые злоумышленником.
  • Dependency compromise: вредоносный пакет попадает в систему через скомпрометированного publisher, dependency confusion или version range, который позднее разрешается иначе.
  • Developer-environment compromise: украденные credentials или измененный source появляются на workstation, в editor, local tool или token еще до того, как код попадает в repository.

Эти маршруты сходятся на runner. Он выполняет команды и получает credentials. Он разрешает зависимости и создает artifacts. Экспортируйте configuration dashboard, проверяйте изменения environment variables и делайте runner credentials недействительными; сохраненный YAML — это не весь pipeline.

Минимальная запись аудита pipeline должна фиксировать execution context. Записывайте выполненные команды, использованные secrets и измененные artifacts. Включайте workflow identity, commit, runner и deployment decision. Одних событий repository недостаточно: слишком многое останется неизвестным.

Используйте SSDF для выбора контролей, а не для заполнения таблицы

NIST опубликовал SP 800-218, SSDF v1.1 в феврале 2022 года. Четыре группы практик:

  • Prepare the Organization (PO): определение людей, политик, процессов и безопасных сред разработки.
  • Protect the Software (PS): защита source code, зависимостей, систем и credentials.
  • Produce Well-Secured Software (PW): безопасные build, test, verify и release программного обеспечения.
  • Respond to Vulnerabilities (RV): выявление, оценка, устранение уязвимостей и информирование о них.

NIST описывает SSDF как основу для планирования, а не таблицу соответствия:

“The SSDF provides a basis for planning and implementing a risk-based approach rather than a checklist to follow.”

Это различие определяет, как использовать framework здесь. PO охватывает ответственность и подготовку среды, включая исключения. PS охватывает source, actions, зависимости, runners и credentials. PW охватывает evidence для build и release. RV охватывает анализ воздействия, устранение и восстановление.

Анонс NIST SSDF v1.2 называет версию 1.2 первоначальным публичным draft, выпущенным 17 декабря 2025 года. Рассматривайте v1.2 здесь как draft guidance; создавайте baseline на основе финальной публикации v1.1. NIST также объявил live DevSecOps guidelines в марте 2026 года; ранее они были открыты для комментариев.

Используйте framework как карту, а затем встраивайте guardrails в свой pipeline.

Защитите source и workflow до сканирования кода

Требуйте review для workflow files, deployment configuration, reusable workflows и любых файлов, способных изменить выполнение или поведение release. Signed commits могут помочь подтвердить авторство, хотя создают дополнительные задачи по key management. Расставляйте их после permissions и action references, если только ваша организация уже хорошо не управляет signing.

Явно задавайте permissions для GitHub Actions:

permissions:
  contents: read

Используйте {}, когда job не нужны repository permissions. Выдавайте write scope только job, которому он необходим. Job, оставляющий комментарии в pull requests, может получить pull-requests: write. Test job по умолчанию не должен получать ни одного разрешения.

В GitHub GITHUB_TOKEN с ограничением contents: read не может отправлять repository contents или создавать releases через этот token. Проверьте job на наличие других credentials и унаследованного доступа.

Будьте осторожны с pull_request_target. Он запускается в контексте base repository и может получить его permissions и secrets. Checkout head commit из fork и запуск его scripts предоставляют коду автора fork доверенный доступ.

Запускайте код из fork в ограниченной среде без repository secrets. Если privileged job должен использовать его output, рассматривайте artifacts как недоверенные bytes: проверяйте их формат перед privileged processing, никогда не выполняйте встроенные scripts и никогда не используйте их для формирования privileged commands.

В терминах SSDF это PS, поскольку controls защищают source и execution inputs до начала production. PO обеспечивает review policy, permission defaults и владельца исключений.

Покупать более крупный scanner до контроля этих маршрутов — неправильный порядок действий.

Сделайте так, чтобы каждый build разрешал именно тот код, который вы намеревались использовать

Закрепляйте third-party actions за проверенными commit SHAs:

# Illustrative abbreviated SHA; production requires the verified full SHA
- uses: tj-actions/changed-files@0e58ed8

Production workflow должен использовать полный 40-символьный commit SHA:

- uses: tj-actions/changed-files@<verified-full-40-character-sha>

Сокращенное значение 0e58ed8 полезно для объяснения разницы между mutable tag и commit reference. Это не полный production pin.

Tag вроде @v45 — это mutable pointer. Как отмечается в техническом разборе Safeguard:

“A git tag is just a mutable pointer, and anyone with push access to the upstream repository — including an attacker who has compromised a maintainer’s account or npm-style publish token — can move it to a different commit at any time.”

Закрепление third-party actions за immutable commit SHAs — один из наименее эффектных и наиболее ценных controls в CI/CD security. Floating tag — это решение о доверии, которое вы принимаете при каждом запуске.

SHA pins создают задачи по обслуживанию. Используйте Dependabot или Renovate для предложения проверенных обновлений. Проверяйте изменения commit, release notes и изменения permissions перед merge. Возврат к floating tags ради удобства сводит контроль на нет.

К зависимостям нужен такой же подход. Коммитьте package-lock.json и poetry.lock. Также коммитьте go.sum. Проверяйте package signatures там, где ecosystem их поддерживает. Отслеживайте неожиданные изменения dependency tree. Не считайте range вроде npm ^1.2.3 достаточным контролем. Используйте в CI install mode package manager, enforcing lockfile, и проверяйте каждое изменение lockfile.

В терминах SSDF SHA pinning и dependency verification защищают software inputs в рамках PS. Получившийся repeatable build поддерживает PW.

Используйте OIDC для доступа к cloud, задав узкую trust policy

Сохраненные cloud credentials могут оставаться действительными, пока кто-то не выполнит их rotation или revocation. OpenID Connect (OIDC) меняет способ аутентификации workflow: job обменивает выданный GitHub JWT на временные provider credentials. Сам JWT не предоставляет cloud access.

Job может объявить:

permissions:
  contents: read
  id-token: write

Затем cloud provider оценивает trust policy. Ограничьте эту policy repository и branch. При необходимости добавьте deployment environment или эквивалентные claims. Token из произвольного repository никогда не должен получать возможность assume вашу production role.

Обычно credentials истекают примерно через час, хотя точный lifetime зависит от provider и configuration. OIDC предпочтительнее долгоживущих cloud secrets, но это не волшебство: плохо заданная trust policy по-прежнему превращает временные credentials в мощные credentials.

Применяйте least privilege дважды. Ограничьте permissions CI job, затем ограничьте actions и resources cloud role. Проверяйте оба набора при изменении workflow.

Masking — не access control. Скомпрометированный step по-прежнему может попытаться извлечь любой secret, доступный его process, а masking точного string может не сработать для закодированного, разделенного, переформатированного или не относящегося к log output.

В терминах SSDF это PS, поскольку control защищает credentials и системы, которые их используют. PO определяет, кто проверяет trust policy и как истекают исключения.

Рассматривайте artifact как свидетельство, которое можно проверить

Обоснованный release содержит evidence о своем output. Создавайте CycloneDX или SPDX software bill of materials (SBOM) в каждом build. SBOM фиксирует components, включая transitive dependencies, чтобы responders могли определить затронутые production artifacts после раскрытия уязвимости.

NIST SSDF v1.1 добавил PS.3.2 для provenance data. Provenance связывает artifact с его source commit, workflow и build environment. Signature устанавливает integrity только в пределах trusted key и policy boundary.

ControlНа какой вопрос отвечаетРекомендуемый response
SBOMГде развернута эта dependency?Поместить затронутые artifacts в quarantine или пересобрать их.
SignatureСоздан ли этот artifact авторизованным process?Отклонить unverifiable artifact.
ProvenanceКакой source и build его создали?Провести investigation или пересобрать из trusted inputs.

Эти controls — operational mapping Blackhawk для PW и RV: создать release evidence, затем использовать его для оценки воздействия и response.

Deployment должен проверять одобренный artifact

Build-time checks теряют ценность, если deployment может выбрать произвольный output. Внедряйте deployment rules как code.

Полезная policy требует signed artifact и approved source repository и branch. Она также проверяет workflow identity и required checks. Сохраняйте digest и source commit как signed metadata. Включайте workflow identity и check results в immutable release record, который может читать deployment policy.

Используйте такую последовательность:

  1. Создайте artifact и сгенерируйте его SBOM и provenance.
  2. Подпишите его через authorized release process.
  3. Требуйте policy checks перед promotion.
  4. При deployment проверьте signature, digest, provenance и required checks.
  5. Подтвердите, что running artifact соответствует approved artifact.
  6. Запишите workflow identity, commit и action SHAs. Запишите runner identity и credential claims. Добавьте artifact digest, выполненные команды, доступ к secrets, изменения artifacts и deployment decision.

По возможности разделяйте build и deployment privileges — test job не должен автоматически обладать production authority. О контролях на стороне облака см. как защищать SaaS-приложения.

Это переход PW к RV: release evidence становится deployment feedback и incident evidence.

Если вы можете сделать только пять вещей, сделайте их в таком порядке

Этот порядок — наше operational judgment, а не универсальный рейтинг, подтвержденный измерениями. Runner isolation, production architecture и release design могут поднять какой-либо пункт выше в вашей среде. Ваш blast radius зависит от среды; измерьте его, прежде чем объявлять работу завершенной.

PriorityControlПочему этот пункт здесьSSDF intent
1Закрепляйте third-party actions за проверенными commit SHAs и автоматизируйте pull requests для обновлений.Это контролирует код, который выполняет каждый job, до того как смогут помочь другие defenses.PS / PW
2Задавайте явные workflow и cloud permissions с принципом least privilege.Это ограничивает ущерб, когда step или action скомпрометирован.PS
3Заменяйте долгоживущие cloud credentials на OIDC с узким доверием.Это сокращает lifetime credentials после ограничения permissions.PS / PO
4Блокируйте и проверяйте зависимости, затем создавайте SBOM для каждого build.Это делает build inputs отслеживаемыми и предоставляет response teams inventory.PS / PW / RV
5Подписывайте и проверяйте release artifacts, используя policy для digest и provenance, а также execution logs.Это контролирует финальный переход от build output к deployment.PW / RV

Пятая строка — это один release-evidence workstream с отдельными implementation tasks. Не принимайте сгруппированное планирование за один огромный gate.

SAST анализирует source code, SCA анализирует dependencies, а secret scanning ищет в source и history материалы, похожие на credentials. Добавьте container scanning, если он создает actionable failure. Не делайте scanner единственной причиной доверия к release.

Назначьте platform team ответственным, а для security создайте путь обработки исключений

Platform или DevOps team должна отвечать за workflow templates, permission defaults, обновления actions, runner configuration и policy checks. Security должна определять baseline, проверять изменения с высоким воздействием и обрабатывать исключения.

Одобрение security для каждого обычного изменения workflow — это очередь, замаскированная под governance. Автоматически завершайте с ошибкой unpinned action, exposed secret, untrusted artifact или изменение production role. Сообщайте findings с более низкой уверенностью, не блокируя pull request.

Для каждого исключения нужны владелец, причина, compensating control, дата истечения и review path. Постоянное исключение — это недокументированное изменение вашей security model.

Developers должны видеть failed control и путь его remediation. Направляйте на escalation новые privileged actions, изменения production role или намеренные policy bypasses.

Это PO в operational form: подготовить organization так, чтобы security work имела владельца, а не превращалась в очередь.

Код с помощью AI по-прежнему входит в ту же цепочку доверия

NIST завершил работу над SP 800-218A, SSDF Community Profile для Generative AI и Dual-Use Foundation Models. Документ предоставляет governance context для teams, использующих AI-assisted development; он не заменяет implementation controls CI/CD.

Код, созданный AI, должен проходить тот же branch protection, dependency verification, testing, secret scanning, provenance и review process, что и написанный человеком код. Его происхождение не подтверждает безопасность. Это делает evidence.

Проблема нулевого количества CVE подчеркивает эту мысль: сканирование известных уязвимостей само по себе не может установить доверие. Фиксируйте source commit, ограничивайте inputs, тестируйте результат и сохраняйте artifact evidence.

Сделайте четыре перехода доверия измеримыми

Определите path как workflow job вместе с credentials, action references, artifacts и deployment target, к которым он может получить доступ. Для каждого path создайте inventory с trigger и token scopes. Записывайте его secrets и cloud role. Включайте его artifact outputs и deployment targets.

Затем контролируйте четыре перехода. Авторизуйте source и ограничивайте build inputs. Сохраняйте artifact evidence и проверяйте deployment. SSDF дает risk-based map; ownership и измеримые условия failure поддерживают ее работоспособность. Начните с jobs с наибольшими privileges и third-party actions.