Блокировка небезопасного кода: аудиты безопасности в GitHub Actions
Проблема: когда деплой становится риском
Тесты прошли, код смёрджен в main
, релиз ушёл в продакшен — а через неделю выходит критическая уязвимость в одной из библиотек. Эксплойты уже на свободе, а вы узнаёте об этом из новостей. Знакомо? Тогда эта статья для вас.
Решение: CI/CD с приоритетом на безопасность
Мы добавим в пайплайн автоматические проверки, которые завалят билд, если найдены уязвимости или проблемы с лицензиями. Пока аудит красный — деплой не начнётся. Это и есть ключевая защита: безопасный путь по умолчанию.
Что и чем мы проверяем
- Уязвимости зависимостей —
bundler-audit
(база RubySec). - Лицензии —
license_finder
(например, блокировка GPL в коммерческих проектах). - OSV база — Google
OSV Scanner
(подходит для смешанных репозиториев).
1# Установка инструментов локально
2gem install bundler-audit license_finder
3
4# Проверка уязвимостей
5bundle audit check --update
6
7# Проверка лицензий
8license_finder --quiet
Вариант 1: аудит и деплой в одном workflow (рекомендуется)
Если ваш deploy.yml
небольшой, добавьте туда шаг аудита и сделайте деплой зависимым от его результата.
1name: Deploy
2
3on:
4 push:
5 branches: [ main ]
6 pull_request:
7 paths: ['Gemfile*', '*.gemspec']
8 schedule:
9 - cron: '0 8 * * MON' # еженедельная проверка безопасности
10
11jobs:
12 audit:
13 name: Security & License Audit
14 runs-on: ubuntu-latest
15 steps:
16 - uses: actions/checkout@v4
17 - uses: ruby/setup-ruby@v1
18 with:
19 ruby-version: .ruby-version
20 bundler-cache: true
21 - run: gem install bundler-audit license_finder
22 - run: bundle audit check --update
23 - run: license_finder --quiet
24 - name: OSV scan
25 uses: google/osv-scanner-action@v1
26 with:
27 scan-args: '--recursive --skip-git .'
28
29 deploy:
30 needs: [audit] # деплой запустится только если аудит прошёл
31 runs-on: ubuntu-latest
32 steps:
33 - uses: actions/checkout@v4
34 # ... шаги деплоя
Ошибка “Unresolved action/workflow reference”?
Проверьте правильность версии action в README. Если action недоступен в Marketplace — установите OSV как бинарь. Это надёжнее и независимее.
Вариант 2: разделение аудита и деплоя (для больших репозиториев)
Вынесите аудит в отдельный workflow и запускайте деплой только после его успешного завершения.
1# .github/workflows/audit.yml
2name: Security Audit
3on:
4 pull_request:
5 paths: ['Gemfile*', '*.gemspec']
6 push:
7 branches: [ main ]
8jobs:
9 audit:
10 runs-on: ubuntu-latest
11 steps:
12 - uses: actions/checkout@v4
13 - uses: ruby/setup-ruby@v1
14 with:
15 ruby-version: .ruby-version
16 bundler-cache: true
17 - run: gem install bundler-audit license_finder
18 - run: bundle audit check --update
19 - run: license_finder --quiet
20 - uses: google/osv-scanner-action@v1
21 with:
22 scan-args: '--recursive --skip-git .'
Что произойдет при обнаружении проблем
- Найдена уязвимость: аудит падает → деплой не запускается → продакшен остаётся в безопасности.
- Конфликт лицензий:
license_finder
помечает пакет → релиз блокируется → команда получает уведомление. - Проблем нет: все проверки зелёные → деплой идёт автоматически.
Мини-чеклист для PR
- Зачем добавляется новая зависимость? Есть ли альтернативы?
- Поддерживается ли пакет активно (релизы, коммиты)?
- Фиксированы ли версии и источник пакета?
- Прошёл ли PR
bundle audit
и проверку лицензий?
Полезные настройки Bundler и альтернативы OSV
Настройки Bundler
1bundle config set disable_multisource true
2bundle config set cache_all true
3bundle config set clean 'true'
Альтернативы и дополнения
- Snyk или Trivy как дополнительный уровень.
- Если action OSV недоступен — используйте CLI-версию утилиты.
- Раз в квартал устраивайте «день гигиены зависимостей» в команде.
Итоги
Один обязательный шаг аудита в CI/CD снижает риск попадания уязвимостей в продакшен в разы. Всё просто: пока красное — релиз не выйдет.
Минимальный набор: включить GitHub Alerts, настроить bundle audit
и проверку лицензий, добавить OSV как второй слой и регулярно обновлять зависимости в команде.