Trivy-сканирование образов в CI
Проблема
Команда собирает Docker-образы, пушит в registry, деплоит в production. Про CVE узнаём, когда security-ресёрчер присылает письмо или когда утром приходит алерт от внешнего сканера. Образ с уязвимым openssl живёт в проде неделями.
Решение
Встроить Trivy в CI-пайплайн как обязательный шаг между docker build и docker push. Билд падает, если найдены HIGH/CRITICAL уязвимости с фиксом — это заставляет обновлять base images, а не игнорировать.
Сам сканер — тоже зависимость с доступом к секретам CI. Action закрепляется по полному SHA коммита, образ — по digest, версия Trivy указывается явно.
Компрометация Trivy, март 2026
19 марта 2026 года вышел вредоносный Trivy v0.69.4, 22 марта — вредоносные образы v0.69.5 и v0.69.6; 75 тегов trivy-action и теги setup-trivy были переписаны на коммиты, крадущие секреты раннера. Затронутыми считаются запуски CI с 19 по 23 марта. Если в этот период Trivy работал в CI по тегу — ротировать все секреты, доступные этим job. Подробности: CSA, SafeDep.
Пример
GitHub Actions:
# .github/workflows/build.yml
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan with Trivy
# v0.36.0, закреплено по SHA: тег можно переписать, коммит — нет
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25
with:
version: v0.76.1 # версия Trivy явно, не latest
image-ref: myapp:${{ github.sha }}
severity: HIGH,CRITICAL
ignore-unfixed: true # не шуметь на CVE без патча
exit-code: 1 # ломать билд
format: sarif
output: trivy.sarif
- name: Upload SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy.sarif # видно в GitHub Security tab
GitLab CI — образ сканера по digest:
# .gitlab-ci.yml
trivy:
stage: test
image:
# digest индекса 0.76.1 по Docker Hub на 2026-10-29; при обновлении взять новый:
# docker buildx imagetools inspect aquasec/trivy:<версия>
name: aquasec/trivy:0.76.1@sha256:790fd66d1697395d8693d1acaa1ea702406a20f109b6fc7bac8db623eca6c06c
entrypoint: [""]
script:
- trivy image --severity HIGH,CRITICAL --ignore-unfixed --exit-code 1 "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA"
Локально перед пушем:
trivy image --severity HIGH,CRITICAL --ignore-unfixed myapp:dev
Когда применять
- Любой репозиторий с Dockerfile, образ которого попадает в production.
- Перед релизом base-образа — как gate, не как отчёт.
Источник
- MichaelCade/90DaysOfDevOps — день про container security
- aquasecurity/trivy
Как применить у себя
- Добавить шаг Trivy в CI, severity
HIGH,CRITICAL,ignore-unfixed: true; action — по SHA, образ — по digest. - Первый прогон: выписать список текущих CVE в issue, починить или осознанно заигнорить через
.trivyignore. - Включить
exit-code: 1и сделать job обязательным для merge. - Когда первый PR упадёт на реальной CVE и команда починит base-образ — статус Изучено.