Статья Управление секретами DevSecOps: архитектура, ротация и детект утечек в Vault, AWS Secrets Manager и Azure Key Vault

Рабочий стол аналитика утром: монитор с графиком аномалий CloudTrail и всплеском запросов, стеклянная доска с архитектурной схемой Vault, AWS SM и Azure KV. Мягкий дневной свет, кофе, латунное прес...


CloudTrail присылает алерт: 340 вызовов GetSecretValue к продакшн-секрету базы данных за 12 минут - при baseline в 8-10 обращений в час. Сервисный аккаунт CI/CD-пайплайна, который штатно дёргает секрет только при деплое, тянет credentials непрерывно. Чуть позднее картина собрана: аккаунт скомпрометирован через утёкший OIDC-токен из лога GitHub Actions, атакующий получил connection string к RDS и начал дамп таблиц. Итог - два часа простоя, утечка PII на 12 000 записей, уведомление регулятора по 152-ФЗ с перспективой оборотного штрафа и полный пересмотр модели доступа к секретам.

Я разбирал шесть похожих инцидентов за последние два года. Пять из шести объединяет одно: секреты лежали в менеджере, но обращения к ним никто не мониторил. Бронированная дверь без камер наблюдения.

Как утекают пароли и API-ключи из CI/CD: kill chain секрета​

1780566580656.webp

Управление секретами DevSecOps на практике часто сводится к задаче «положить пароль в Vault и забыть». Kill chain реальной утечки секрета выглядит иначе:
  1. Initial Access - атакующий получает доступ к CI/CD-пайплайну. Типичные векторы: утёкший токен в репозитории, YAML-инъекция в self-hosted агенте, OAuth token theft. Pipeline secret leakage фигурирует в рекомендациях Microsoft как recurring issue для Azure DevOps и GitHub Enterprise.
  2. Credential Access - через скомпрометированный пайплайн атакующий обращается к секрет-менеджеру с легитимными правами сервисного аккаунта. Vault отдаёт секрет по валидной policy, AWS SM - по IAM role. Никаких алертов.
  3. Collection и Exfiltration - полученные credentials используются для прямого доступа к базам данных, API, облачным ресурсам. Секрет-менеджер на этом этапе уже не при делах.
Ключевой момент - этап 2. Атакующий не взламывает Vault или Secrets Manager. Он использует легитимный доступ скомпрометированного сервиса. Шифрование at rest и in transit здесь бесполезно: секрет отдаётся по валидному запросу. Единственный способ поймать такое - мониторинг паттернов обращений и сравнение с baseline. NIST CSF v2.0 формализует это в субкатегории DE.AE-01: «A baseline of network operations and expected data flows for users and systems is established and managed»«Устанавливается и поддерживается базовый уровень сетевых операций и ожидаемых потоков данных для пользователей и систем».

Показательный пример атаки на инфраструктуру вокруг секретов - CVE-2026-9133 (CVSS 8.3 HIGH, CWE-489 - Active Debug Code): оставленная в production debug-схема ARN (arn:aws-debug:file) в эндпоинте PUT /api/aws/arn/validate плагина rabbitmq-aws (до версии 0.2.1). Аутентифицированный удалённый пользователь мог прочитать произвольные файлы, доступные процессу RabbitMQ - включая TLS-сертификаты и приватные ключи. Доступ к секретам шёл на уровне файловой системы, минуя Secrets Manager API. CloudTrail этого не видел вообще. Attack surface управления API-ключами и credentials шире, чем интерфейс самого менеджера, - и про это регулярно забывают.

Сравнение инструментов: HashiCorp Vault, AWS Secrets Manager и Azure Key Vault​

1780567397838.webp

Почему эти три и что осталось за рамками​

Vault, AWS Secrets Manager и Azure Key Vault - три архитектурно разных подхода к хранению паролей и токенов в CI/CD: multi-cloud с полным контролем (Vault), managed-сервис для AWS-native стека (Secrets Manager), решение для Microsoft-хозяйства (Key Vault). Все три активно поддерживаются: Vault - open-source с BSL-лицензией, релизы ежеквартально, плюс HCP Vault Dedicated как managed-вариант; AWS SM и Azure KV - managed-сервисы с SLA от провайдера.

За рамками остались: Doppler (SaaS-only - секреты транзитом через чужую инфраструктуру, ряд compliance-фреймворков это запрещает), CyberArk Conjur (PAM-first архитектура, не secrets-first), GCP Secret Manager (архитектурно аналогичен Azure KV, но с меньшей долей в enterprise-сегменте RU).

КритерийHashiCorp VaultAWS Secrets ManagerAzure Key Vault
Динамические секретыДа, 20+ backends (DB, AWS, PKI, SSH)Нет, статическая ротация через LambdaНет, статическая ротация
Audit logJSON audit device, каждый запрос, HMAC accessorCloudTrail (GetSecretValue, PutSecretValue)Diagnostic logs + Event Grid
SIEM-интеграцияsyslog/file/socket -> любой SIEMCloudTrail -> CloudWatch -> SIEMDiagnostic Settings -> Log Analytics / Event Hub
Модель ротацииLease TTL (минуты-часы), автоматический revokeLambda, built-in для RDS/Redshift/DocumentDBEvent Grid + custom handler
Failure mode при ротацииСтарый lease живёт до TTL expiryTwo-user: два набора credentials валидны одновременноВерсионирование, старая версия доступна
Multi-cloudДаТолько AWSТолько Azure / Microsoft 365
СтоимостьOSS бесплатно; HCP Vault Dedicated - цена зависит от тира и региона, актуальное на cloud.hashicorp.com/pricing/vault$0.40/секрет/мес + API-вызовыStandard: бесплатно (лимит операций); Premium (HSM): $1/ключ/мес
HSM-защитаEnterprise + cloud KMS auto-unsealAWS KMS (FIPS 140-2 validated, HSM-модули Level 3)Premium: FIPS 140-3 Level 3

Когда что брать:
  • Vault - multi-cloud или гибрид, нужны динамические секреты Vault, максимальный контроль над audit. Но за это платишь operational overhead: продакшн-кластер требует HA-конфигурации на Raft или Consul, настройки auto-unseal через AWS KMS или Azure Key Vault (в роли KMS-backend, не как secrets manager), выделенной ops-экспертизы. Я разворачивал Vault-кластер на 3 ноды с Raft - только на отладку auto-unseal через AWS KMS ушло два дня.
  • AWS Secrets Manager - full-AWS стек, managed ротация RDS/Redshift, минимум ops. Но vendor lock-in, per-secret pricing кусается при тысячах секретов, а гранулярность audit слабая - CloudTrail это общий поток для всего аккаунта, secret-related events тонут в шуме.
  • Azure Key Vault - Microsoft-стек, Entra ID как IdP, HSM на Premium tier с FIPS 140-3 Level 3. Вне Azure интеграция слабая; типичная misconfiguration из advisory - legacy access policies вместо RBAC mode, что ограничивает granular audit и открывает дорогу для secret enumeration.
При работе с Kubernetes разница в интеграции ощутима. Vault Agent работает как sidecar или init-container, аутентифицируясь через Kubernetes auth method (service account token), и проактивно перезапрашивает секреты при приближении lease expiry. AWS Secrets Manager подключается через CSI Driver для EKS, Azure Key Vault - через Azure Key Vault Provider for Secrets Store CSI Driver. Vault Agent обновляет credentials при ротации немедленно, а облачные CSI-драйверы опрашивают менеджер по расписанию (rotation polling interval) - и создают окно с устаревшими credentials в поде. На практике это означает, что после ротации пароля в AWS SM поды могут минуту-другую ходить со старыми кредами.

Ротация credentials и динамические секреты Vault: что ломается в середине деплоя​

Автоматизация управления секретами - вопрос не только безопасности, но и доступности. Вот что реально происходит при ротации credentials в каждой системе.

Vault: динамические секреты как архитектурное решение. Vault не ротирует общий пароль - он выдаёт каждому потребителю уникальный credential с lease TTL. Приложение запрашивает доступ к PostgreSQL, Vault создаёт временного пользователя БД с TTL в 1 час. По истечении lease Vault отзывает credentials автоматически. Нет shared password, нечего ротировать глобально, компрометация одного lease не затрагивает остальных. Blast radius измеряется часами, а не месяцами. Но есть нюанс: не все legacy-сервисы умеют работать с обновляемыми credentials. Если ваше приложение при старте читает пароль из конфига и больше его не перечитывает - Vault Agent с template rendering решает проблему, но требует доработки деплоя.

AWS Secrets Manager: two-user rotation. При ротации пароля RDS Lambda-функция создаёт нового пользователя БД, обновляет секрет в менеджере, а старый пользователь остаётся активным до следующего цикла. Zero-downtime гарантирован, но возникает окно, когда два набора credentials валидны одновременно. С точки зрения detection: одновременное использование обоих наборов из разных source IP - аномалия и IOC.

Azure Key Vault: версионирование. Каждое обновление секрета создаёт новую версию, старая доступна по прямому URI. Для zero-downtime Microsoft рекомендует dual credentials. Event Grid отправляет SecretNearExpiry, но advisory-паттерн Azure фиксирует типичную проблему: race condition при auto-rotation сертификатов - приложение считывает старую версию до завершения ротации. Если вы видите в логах чтение двух разных версий одного секрета из одного сервиса с интервалом в секунды - скорее всего, race condition, а не атака. Если из разных IP - уже другой разговор.

Автоматизация управления секретами: аудит и корреляция аномалий в SIEM​

Требования к окружению:
📚 Часть контента скрыта. Этот материал доступен участникам сообщества с рангом One Level или выше
Получить доступ просто — достаточно зарегистрироваться и проявить активность на форуме


Типичная ошибка в Vault policies, которую я вижу регулярно: path "secret/data/[I]" { capabilities = ["read"] } - даёт сервису доступ ко всему дереву prod-секретов. Скомпрометированный CI-аккаунт с такой policy спокойно прочитает credentials от платёжного шлюза, хотя штатно ему нужен только пароль от staging-базы. Правильный подход - per-service policy с конкретными путями: path "secret/data/prod/service-a/[/I]".

AWS CloudTrail. Событие GetSecretValue содержит ARN секрета, source IP и user identity. Базовый фильтр: eventName = "GetSecretValue" с группировкой по requestParameters.secretId. Строите baseline: количество вызовов на секрет в час, список source IP для каждой IAM role. Аномалия: burst выше 3-sigma от baseline, новый IP, обращение к секрету, к которому роль раньше не обращалась.

Azure Key Vault. Включить Diagnostic Settings с категорией AuditEvent -> Log Analytics или Event Hub. KQL для поиска аномального burst:
Код:
AzureDiagnostics
| where ResourceProvider == "MICROSOFT.KEYVAULT"
| where OperationName == "SecretGet"
| summarize cnt=count() by CallerIPAddress, bin(TimeGenerated, 1h)
| where cnt > 50
Для Azure Key Vault критично перейти с legacy access policies на RBAC mode - access policies не дают granular разграничения и хуже логируются. Обязательны soft-delete и purge protection: без них атакующий может удалить секрет без возможности восстановления.

Insider threat: скомпрометированный сервисный аккаунт. Самый тяжёлый сценарий для detection - атакующий действует от имени легитимного сервиса. Признаки: обращение к секретам вне нормального расписания (деплой в 3 ночи при baseline 9-18), чтение секретов, к которым сервис имеет доступ по policy, но раньше не обращался, обращение с нового IP при стабильном Vault Agent в Kubernetes. IP пода в K8s не должен меняться между запросами в рамках одного lease - если меняется, это либо переезд пода на другую ноду, либо подмена.

Detection-чеклист: что передать в SOC​

  1. Включить audit logging на всех секрет-менеджерах: Vault - audit device (file или socket), AWS - CloudTrail в каждом регионе, Azure - Diagnostic Settings с категорией AuditEvent
  2. Построить baseline обращений к каждому продакшн-секрету: количество в час, список source IP, привязка к accessor или IAM role
  3. Алерт на burst: более N обращений к одному секрету за 15 минут (N = 3× baseline; пример: 20 при baseline 6/час) - порог адаптировать под свой baseline
  4. Алерт на «первое обращение»: accessor или роль читает секрет, к которому раньше не обращалась - IOC для lateral movement через секреты
  5. Корреляция: обращение к секрету + подключение к целевому ресурсу (RDS, API) с нового IP - объединять CloudTrail или Vault audit с VPC Flow Logs и NSG Flow Logs
  6. Azure Key Vault: перейти с access policies на RBAC mode
  7. Включить soft-delete + purge protection для Azure Key Vault
  8. Vault: ревизия policies на wildcard-path - path "secret/*" даёт доступ ко всему дереву
  9. Алерт на ListSecrets и list операции - enumeration секретов обычно предшествует exfiltration
  10. Ротация: убедиться, что rotation function (Lambda, Event Grid handler) - единственный источник write-операций к секретам. PutSecretValue от другого principal - инцидент
Этот чеклист можно распечатать и отнести в SOC как есть. Или адаптировать под свой SIEM - суть не изменится.

Заключение​

За два года я участвовал в разборе шести инцидентов с утечкой секретов. В пяти секрет-менеджер был развёрнут и работал штатно. Проблема была не в хранении - никто не смотрел, кто и как часто к секретам обращается. Динамические секреты Vault частично закрывают вопрос: каждый lease уникален и короткоживущий. Но даже с Vault без мониторинга вы не узнаете, что скомпрометированный pod запрашивает credentials к продакшн-базе каждые 30 секунд вместо штатного раза в час.

Cloud-native менеджеры (AWS Secrets Manager, Azure Key Vault) дают заметно более слабый audit по сравнению с Vault. CloudTrail - общий поток событий всего AWS-аккаунта, secret-related events там - иголка в стоге сена без отдельной фильтрации и выделенного trail. Azure Key Vault удобнее для lifecycle-автоматизации за счёт Event Grid, но Diagnostic Logs выключены по умолчанию (и об этом забывают с завидным постоянством).

Если у вас мультиоблако и SIEM-стек с фокусом на detection - Vault даёт единообразный поток аудита по всем средам. Проверьте прямо сейчас: включён ли audit device на вашем Vault? Есть ли алерт на burst GetSecretValue в CloudTrail? Если на оба вопроса ответ «нет» - у вас та же проблема, что была у пяти из шести моих кейсов. Если адаптируете правила мониторинга secret access под свой SIEM - на codeby.net коллеги делятся шаблонами корреляции Vault audit и CloudTrail-событий Secrets Manager с привязкой к конкретным стекам.
 
Последнее редактирование модератором:
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab