Security In CI CD
🚀 Как защитить CI/CD пайплайн? Best Practices для DevOps
CI/CD пайплайн – одна из самых уязвимых частей инфраструктуры, потому что он имеет доступ ко всем компонентам продакшена. Если злоумышленник скомпрометирует CI/CD, он сможет выполнять код в проде, красть секреты и модифицировать образы.
Разберем ключевые best practices, чтобы защитить CI/CD.
1️⃣ Защита секретов в CI/CD
Проблема: Секреты в коде → утечка токенов и паролей.
Решение: Используем защищенные хранилища секретов, а не .gitlab-ci.yml.
✅ Как правильно?
• Использовать HashiCorp Vault / AWS Secrets Manager для хранения API-ключей.
• GitLab CI/CD → CI/CD Variables (masked, protected).
• Не передавать секреты как аргументы команд (--password=secret).
📌 Пример безопасного использования секретов в GitLab CI:
deploy:
script:
- export DB_PASSWORD=$CI_DB_PASSWORD # Переменная из GitLab CI/CD
- ./deploy.sh
variables:
CI_DB_PASSWORD: "MASKED" # Переменная не логируется в CI
🚨 Опасно:
❌ Хранить пароли в коде (.gitlab-ci.yml).
❌ Записывать секреты в логи CI/CD (echo $DB_PASSWORD).
2️⃣ Ограничение прав в CI/CD
Проблема: GitLab Runner работает с root-доступом → может выполнять вредоносный код.
Решение: Ограничиваем права и доступ к Runner’ам.
✅ Как правильно?
• Запускать GitLab Runner в Kubernetes (gitlab-runner helm chart).
• Ограничить права Runner’а (rootless CI/CD).
• Использовать защищенные раннеры для production (protected runners).
📌 Как назначить раннер только для protected branch?
gitlab-runner register --locked --access-level=ref_protected
🚨 Опасно:
❌ Использовать общий runner для всех разработчиков → любой может изменить прод.
❌ Запускать docker-in-docker (dind) без --privileged=false → полный доступ к системе.
3️⃣ Проверка кода перед деплоем (SAST, DAST, IaC Security)
Проблема: Уязвимости в коде и инфраструктуре → эксплойты, SQL-инъекции, RCE.
Решение: Автоматическая проверка кода перед развертыванием.
✅ Как правильно?
• SAST (Static Analysis Security Testing) → SonarQube, GitLab SAST.
• DAST (Dynamic Analysis Security Testing) → OWASP ZAP, Nikto.
• Проверка инфраструктуры (IaC Security) → Checkov, tfsec, kube-score.
📌 Пример интеграции SAST в GitLab CI:
sast:
stage: test
script:
- gitlab-sast-check
📌 Пример проверки Terraform-кода на уязвимости:
iac-security:
stage: test
script:
- pip install checkov
- checkov -d .
🚨 Опасно:
❌ Не проверять код перед деплоем → уязвимости попадают в прод.
❌ Игнорировать сканирование инфраструктуры (tfsec, checkov) → Terraform может создать дырку в безопасности.
4️⃣ Подпись и верификация контейнеров
Проблема: Запуск непроверенных Docker-образов → supply chain атаки.
Решение: Подписывать образы и проверять их перед деплоем.
✅ Как правильно?
• Используем Sigstore Cosign / Notary для подписи контейнеров.
• Сканируем образы на уязвимости (Trivy, Clair, Anchore).
• Запрещаем запуск непроверенных образов в Kubernetes (OPA/Gatekeeper).
📌 Пример подписи образа с Cosign:
cosign sign --key cosign.key myrepo/myapp:latest
cosign verify --key cosign.pub myrepo/myapp:latest
📌 Как запретить неподписанные образы в Kubernetes (OPA/Gatekeeper)?
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPContainerAllowedImages
metadata:
name: enforce-signed-images
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
parameters:
allowedImages:
- "myrepo.com/*"
🚨 Опасно:
❌ Запускать latest без проверки версии.
❌ Не проверять уязвимости в образах (docker scan).
5️⃣ Защита артефактов и кеша в CI/CD
Проблема: Артефакты билдов и кеши могут содержать чувствительные данные.
Решение: Ограничиваем доступ к артефактам и шифруем их.
✅ Как правильно?
• Очищаем артефакты после билда (expire_in).
• Ограничиваем доступ к кешу (cache: policy: pull-only).
📌 Пример очистки артефактов через 1 день:
artifacts:
expire_in: 1 day
📌 Пример запрета загрузки кеша неавторизованными пользователями:
cache:
policy: pull-only
🚨 Опасно:
❌ Хранить чувствительные данные в артефактах (например, .env файлы).
6️⃣ Контроль доступа к CI/CD (Branch Protection & MR Rules)
Проблема: Любой разработчик может деплоить код в прод.
Решение: Настроить защиту веток и мерж-реквестов.
✅ Как правильно?
• Включаем защиту main / master (branch protection).
• Ограничиваем, кто может делать merge (Code Owners).
• Обязательный CI/CD pipeline перед мерджем (merge checks).
📌 Как включить защиту ветки в GitLab?
gitlab project settings → Protected Branches → Protect "main"
📌 Как запретить merge без CI/CD проверки?
only:
- main
- staging
🚨 Опасно:
❌ Давать всем доступ к merge в main.
❌ Разрешать деплой без CI/CD-проверки.
🎯 Итог: Как защитить CI/CD?
Категория | Best Practice |
---|---|
Секреты | Использовать Vault, GitLab CI/CD Variables, Masked Variables |
Доступ | Ограничить runner’ы, запретить root-права |
Сканирование | Использовать SAST, DAST, Checkov, Trivy |
Образы | Подписывать (cosign), сканировать, проверять OPA |
Артефакты | Очищать (expire_in), запрещать pull из кэша |
Branch Protection | Ограничить merge, проверять через MR |