Секреты и окружения в GitHub Actions: безопасная настройка деплоя
Практика3 минРедакция Innovialabs
Коротко
Храните продакшен-доступы в секретах окружения с обязательными ревьюерами и ограничением веток, замените долгоживущие облачные ключи на OIDC, урежьте права GITHUB_TOKEN и никогда не запускайте код из форков рядом с секретами.
Коротко
Безопасный деплой в GitHub Actions держится на четырёх принципах:
- Узкая область секретов: продакшен-доступы лежат в окружении
production, а не на уровне репозитория. - Контроль продакшена: окружение требует одобрения ревьюера и принимает деплой только из защищённых веток.
- Никаких долгоживущих облачных ключей: workflow получает временные доступы через OIDC.
- Логи и форки — зона риска: маскирование не гарантирует защиту, а чужой код не должен выполняться рядом с секретами.
Три уровня секретов
| Уровень | Кто может использовать | Для чего |
|---|---|---|
| Организация | Репозитории, выбранные в политике доступа | Общие значения: токены реестра, вебхуки уведомлений |
| Репозиторий | Любой workflow в репозитории | Некритичные значения для разных джобов |
| Окружение | Только джобы, ссылающиеся на окружение, и только после прохождения правил защиты | Доступы для деплоя в staging и production |
При совпадении имён побеждает более конкретный уровень: окружение важнее репозитория, репозиторий — организации. Секреты читаются через ${{ secrets.NAME }}, и передавать их в шаги лучше через env, а не вставлять прямо в скрипт.
Как защитить продакшен
В Settings → Environments → production настройте:
- Required reviewers — человек или команда должны одобрить каждый деплой-джоб до его запуска и до выдачи секретов.
- Deployment branches and tags — разрешите только
mainили релизные теги. Тогда feature-ветка не задеплоит, даже если кто-то изменит workflow. - Wait timer, если нужна пауза перед деплоем.
- Запрет самоодобрения, где он доступен, чтобы автор изменения не мог одобрить собственный деплой.
Дополните это branch protection или rulesets для main: обязательные ревью pull request, обязательные проверки и запрет force push. Иначе любой с правами записи сможет запушить изменённый workflow прямо в защищённую ветку.
OIDC вместо облачных ключей
Статичные ключи доступа в секретах живут месяцами и работают откуда угодно. С OIDC GitHub выпускает подписанный токен для каждого запуска, а облачный провайдер обменивает его на временные доступы — только если claims токена совпадают с политикой доверия (репозиторий, ветка, окружение).
name: deploy
on:
push:
branches: [main]
permissions:
contents: read
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/github-deploy
aws-region: eu-central-1
- run: ./scripts/deploy.sh
На стороне облака ограничьте политику доверия точным subject, например окружением production конкретного репозитория. Wildcard на всю организацию сводит пользу к нулю. Такой сценарий поддерживают крупные облака и Vault.
Как утекают секреты
Через логи:
- GitHub маскирует точные значения секретов, но не преобразованные: в base64, разбитые на части, URL-кодированные или внутри JSON.
set -x, подробный режим CLI и debug-логирование могут вывести заголовки и токены.- Производные значения регистрируйте через
echo "::add-mask::$VALUE"до использования.
Через форки и чужой код:
- Workflow по событию
pull_requestиз форков не получают секретов — так и должно оставаться. pull_request_targetиworkflow_runработают с секретами основного репозитория. Если в них сделать checkout и запустить код из PR, ваши секреты получит любой внешний участник.- Данные вроде заголовка PR или имени ветки, вставленные прямо в
run:, открывают путь к инъекции команд. Передавайте их черезenvи в кавычках.
Через зависимости:
- Сторонние actions работают с правами вашего джоба. Закрепляйте их на полный SHA коммита и проверяйте, что они делают.
Чек-лист минимальных прав
- Задайте
permissions:на уровне workflow; начните сcontents: readи добавляйте только нужное. - Храните продакшен-секреты только в окружении
production. - Меняйте любой секрет, который хоть раз попал в лог, коммит или чат.
- Удаляйте неиспользуемые секреты и окружения.
- Проверьте, у кого есть права администратора: они могут менять правила защиты.