Статья A.S Groups

GitHub Actions cache-mode: как защитить CI/CD-кэш от poisoning

GitHub Actions cache-mode и защита CI/CD-кэша от cache poisoning

Навигация по статье

Услуги A.S Groups

Нужен сайт, магазин или автоматизация?

Помогаю бизнесу запускать и дорабатывать WordPress-проекты: от посадочной страницы до WooCommerce, CRM и Telegram-уведомлений.

Обсудить проект Telegram
WordPress под ключ Лендинги, корпоративные сайты и структура под заявки. WooCommerce Интернет-магазины, каталог, оплата, доставка и интеграции. Доработка сайта Правки, скорость, формы, баги и развитие текущего проекта. CRM / Telegram / AI Автоматизация заявок, уведомлений и ручных процессов.

10 сентября 2026 года GitHub объявил общую доступность cache-mode для GitHub Actions. Новый ключ позволяет явно ограничить, может ли workflow или отдельный job читать кэш, записывать его, делать оба действия или полностью работать без доступа к кэшу.

Изменение выглядит небольшим, но касается важной границы доверия в CI/CD. Кэш ускоряет сборки, однако вредоносное или непроверенное содержимое кэша может попасть в более привилегированный workflow. Поэтому GitHub связывает cache-mode с принципом least privilege и отдельно предупреждает о риске cache poisoning.

Что такое cache-mode в GitHub Actions

cache-mode задаётся на уровне всего workflow или конкретного job. GitHub применяет ограничение через scoped cache tokens: job не может восстановить или сохранить кэш сверх разрешённого режима.

Режим Restore Save Типичный сценарий
read Да Нет Проверки из недоверенного контекста
write Да Да Доверенная сборка, которая поддерживает кэш
write-only Нет Да Job создаёт кэш, но не должен потреблять существующий
none Нет Нет Job вообще не нуждается в GitHub Actions cache

Если режим не указан, GitHub выбирает значение по умолчанию в зависимости от типа события. Для low-trust triggers действует более ограничительная модель доступа.

Почему кэш вообще становится security-границей

Кэш GitHub Actions часто содержит зависимости, промежуточные файлы сборки, артефакты package manager или скомпилированные данные. Workflow, который восстанавливает такой кэш, фактически доверяет его содержимому настолько, насколько доверяет процессу, который этот кэш создал.

Если низкодоверенный workflow способен записать данные в область кэша, которую позже читает привилегированный workflow, появляется цепочка для cache poisoning. В худшем случае доверенная сборка может использовать подменённые файлы и выполнить код в контексте, где доступны дополнительные права или secrets.

GitHub подчёркивает: восстановленный кэш нужно рассматривать как недоверенный ввод. В кэше также не следует хранить секреты и чувствительные данные.

Безопасный default для low-trust triggers

Для событий с низким уровнем доверия GitHub применяет read-only доступ к кэшу default branch. В документации среди таких сценариев отдельно рассматриваются pull_request_target, issue_comment и workflow_run.

Это позволяет job использовать уже существующий кэш, но не создавать или перезаписывать записи, способные повлиять на другой workflow. Если save запрещён эффективным режимом, операция пропускается; сам job из-за этого не обязан падать.

Главная ловушка: явный write отменяет безопасное ограничение

Самая важная часть нового механизма — cache-mode может не только усилить, но и ослабить защиту. Если для low-trust trigger явно задать write или write-only, GitHub разрешит запись и покажет warning annotation.

То есть конфигурация ниже требует отдельного security review:

on:
  pull_request_target:

cache-mode: write

Такая запись не означает автоматическую уязвимость, но она возвращает возможность сохранять кэш из контекста, который GitHub по умолчанию считает низкодоверенным. Если job обрабатывает код из fork или другой непроверенный ввод, риск становится существенно выше.

Как использовать read для проверки pull request

Для job, которому нужен кэш только ради ускорения тестов, безопаснее явно оставить чтение:

cache-mode: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/cache@v4
        with:
          path: ~/.npm
          key: npm-${{ hashFiles('**/package-lock.json') }}
      - run: npm ci
      - run: npm test

Тогда job может получить существующий кэш, но не публикует новый. Если кэш нужно обновлять, GitHub рекомендует делать это из доверенного workflow, например запускаемого событием push.

Job-level cache-mode даёт более точную модель прав

Необязательно назначать один режим всей автоматизации. Значение на уровне jobs.<job_id>.cache-mode переопределяет workflow-level настройку для конкретного job.

cache-mode: read

jobs:
  test:
    runs-on: ubuntu-latest
    cache-mode: read

  trusted-build:
    runs-on: ubuntu-latest
    cache-mode: write

Практическая идея проста: не давать право записи всем job только потому, что оно требуется одному этапу сборки. Это тот же least-privilege подход, который применяют к permissions, токенам и secrets.

Что происходит с reusable workflows

cache-mode распространяется и на reusable workflows. Явно установленное ограничение вызывающего job задаёт верхнюю границу доступа для вызываемого workflow.

Например, если caller разрешает только read, reusable workflow не может повысить доступ до write. GitHub отклонит несовместимую конфигурацию ещё до выполнения. Это важно для общих корпоративных workflow, которые используются десятками репозиториев.

Когда полезен write-only

write-only — менее очевидный режим. Он запрещает restore, но разрешает save. Такой вариант подходит для отдельного доверенного job, задача которого — подготовить свежий кэш для последующих запусков, не используя существующее содержимое как входные данные.

Это помогает разорвать обратную зависимость: job создаёт состояние, но сам не доверяет ранее записанному кэшу.

Когда стоит поставить none

Если job не использует кэш, лучше запретить доступ явно через none. Это не ускорит workflow и не заменит другие permission-настройки, но уменьшит доступную поверхность.

Особенно полезно делать это в служебных jobs, которые только проверяют метаданные, публикуют статус или выполняют действия, не связанные с dependency cache.

Что проверить в существующих GitHub Actions

  • какие workflows используют actions/cache или встроенное caching package managers;
  • какие events запускают эти workflows;
  • есть ли pull_request_target, issue_comment или workflow_run;
  • обрабатывается ли в таком job код или ввод из недоверенного источника;
  • каким jobs реально требуется право save;
  • можно ли вынести обновление кэша в доверенный push-workflow;
  • какие reusable workflows вызываются и какое cache permission они получают;
  • не хранятся ли в cache секреты или чувствительные файлы.

cache-mode не заменяет обычные permissions

Новый ключ управляет именно GitHub Actions cache. Он не заменяет ограничения GITHUB_TOKEN, permissions репозитория, environment protection, secrets или sandboxing runner.

Поэтому аудит CI/CD лучше проводить слоями: права токена, события запуска, доступ к кэшу, работа с secrets, доверие к checkout-коду, third-party actions и тип runner. Отдельный полезный шаг — проверять dependencies и supply chain. Недавно я разбирал доступ Dependabot к приватным GitHub Packages без PAT и обновления CodeQL 2.27.

Что это меняет для DevOps-практики

Раньше команда могла контролировать permissions токена достаточно подробно, но cache access оставался менее явной частью модели. С cache-mode кэш становится отдельным настраиваемым permission-like слоем.

Для больших репозиториев это особенно полезно вместе с reusable workflows и централизованными шаблонами. Можно зафиксировать безопасные defaults и выдавать write только тем jobs, где он действительно нужен. Для self-hosted GitHub-инфраструктуры похожий принцип контроля прав стоит применять и при обновлениях платформы — например, в материале о GitHub Enterprise Server 3.22.

Официальные источники

Итог

cache-mode делает доступ к GitHub Actions cache явным и позволяет применять least privilege отдельно для каждого workflow или job. Для обычной доверенной сборки write остаётся нормальным вариантом, но low-trust triggers лучше не наделять записью без конкретной причины и отдельной проверки.

Если нужно разобрать существующие GitHub Actions, reusable workflows, webhooks или автоматизацию CI/CD, можно описать задачу A.S Groups. Сначала стоит составить карту событий и прав, а уже затем менять production workflow.

Следующий шаг

Нужно решить похожую задачу?

Связать изменение с аудитом CI/CD и GitHub Actions без обещаний абсолютной безопасности.

Обсудить задачу

Источники

Обсуждение

Вопросы и комментарии

Можно уточнить детали статьи или поделиться своим опытом. Первый комментарий проходит проверку.

Оставить комментарий

Email не публикуется. Ссылки и HTML в тексте удаляются.

Мы используем приватную аналитику SlimStat, чтобы понимать, какие страницы полезны посетителям, и улучшать сайт. IP-адреса анонимизируются и хэшируются. Вы можете согласиться или отказаться от аналитики.
Cookies и конфиденциальность

Используем необходимые cookies, аналитику и данные форм, чтобы сайт работал корректно и заявки доходили.