HashiCorp Vault: централизованное хранение секретов и политики доступа

0
10
Обложка статьи: HashiCorp Vault: централизованное хранение секретов и политики доступа

Переменные CI и поиск секретов в git закрывают конкретные частные случаи. Там, где приложений и секретов много — несколько команд, несколько сред, десятки сервисных учётных записей — нужен отдельный централизованный сервис, который хранит секреты, выдаёт их по политике и ведёт историю версий. HashiCorp Vault — такой сервис с открытым исходным кодом.

Статья опирается на логику направления «Безопасность данных» из методики зрелости Группы Сбер (источник); это методика для крупных компаний, мы используем её как ориентир и пересказываем своими словами. Проверка выполнена на Vault в тестовом режиме (dev) в контейнере, после неё всё удалено.

Что должно получиться

Уровень Что это значит на практике
2. Гигиенический Секреты приложений хранятся в централизованном сервисе с политиками доступа, а не в коде, переменных окружения без контроля или общем чате команды

Критерии сформулированы нами по мотивам методики, это ориентир, а не оценка соответствия.

Запись и чтение секрета

vault kv put secret/myapp/db password=СЛОЖНЫЙ_ПАРОЛЬ user=app_owner
vault kv get secret/myapp/db

Приложение не хранит пароль у себя — оно запрашивает его у Vault при старте, используя собственный токен. Важная оговорка: режим dev, использованный для проверки (vault server -dev), автоматически распечатывает хранилище и хранит данные только в памяти — для реальной эксплуатации нужен обычный режим с настроенным физическим хранилищем и ручным или автоматическим процессом распечатывания (unseal), который здесь не рассматривается.

Политика доступа только на чтение

Выдавать приложению корневой токен (как в примере выше) недопустимо — у него тогда будет доступ ко всему хранилищу. Политика ограничивает токен конкретным путём и действием:

path "secret/data/myapp/*" {
  capabilities = ["read"]
}
vault policy write myapp-ro myapp-ro.hcl
vault token create -policy=myapp-ro -ttl=1h

Ключ -ttl ограничивает срок жизни токена — после истечения приложению нужно получить новый, что снижает ущерб от утечки токена по сравнению с бессрочным доступом.

Результат проверки

Действие токеном с политикой myapp-ro Результат
Прочитать секрет по разрешённому пути (secret/myapp/db) Успех, данные получены
Записать новое значение по тому же пути Отказ: permission denied
Прочитать секрет по другому пути (secret/other-app/db) Отказ: permission denied
Использовать токен после истечения срока жизни (TTL 10 секунд в тесте) Отказ: invalid token

Политика и ограничение по времени жизни токена работают именно так, как заявлено: токен не может выйти за пределы разрешённого пути и действия, и перестаёт работать по истечении срока без дополнительных действий.

Версионирование секретов

Хранилище типа KV версии 2 (используется по умолчанию в современных версиях) хранит историю изменений секрета:

vault kv get -version=1 secret/myapp/db   # предыдущее значение пароля
vault kv get secret/myapp/db              # текущее (последняя версия)

В тесте после повторной записи нового пароля запрос с явным номером версии корректно вернул старое значение, а запрос без номера — новое. Это полезно при разборе инцидента: можно увидеть, каким был секрет на конкретный момент, без отдельной системы журналирования паролей.

Порядок внедрения

  1. Разверните Vault в обычном (не dev) режиме с постоянным хранилищем и настройте процесс распечатывания при перезапуске.
  2. Заведите отдельный путь и политику для каждого приложения, а не общий путь «на всё» — узкая политика ограничивает ущерб при утечке конкретного токена.
  3. Используйте короткоживущие токены там, где это возможно (CI, временные задачи), и регулярно продлеваемые — для постоянно работающих сервисов.
  4. Включите аудит-лог Vault — отдельный журнал всех обращений к секретам, не смешанный с обычными журналами приложений.
  5. Переносите секреты поэтапно, начиная с самых критичных (пароли к продуктивным базам), не пытайтесь мигрировать всё сразу.

Диагностика

Симптом Причина и что делать
Все приложения используют корневой токен Миграция сделана наспало без политик. Заведите отдельную политику на каждое приложение, даже если это требует времени
После перезапуска сервера Vault недоступен В обычном режиме хранилище нужно распечатать (unseal) после каждого запуска процесса, если не настроен автоматический механизм. Это ожидаемое поведение, не сбой
Приложение теряет доступ к секретам в середине дня Истёк срок жизни токена. Настройте продление (renew) или увеличьте TTL для долгоживущих сервисов
Нужно узнать, кто и когда читал секрет Без включённого аудит-лога эта информация не сохраняется. Включите аудит-устройство до того, как он понадобится при разборе инцидента

Где это в модели зрелости

Материал относится к направлению «Безопасность данных» (материалы направления, карта зрелости). Уровень 2 требует контролируемого доступа к чувствительным данным: централизованное хранение секретов с политиками и аудитом закрывает конкретный риск — пароли и ключи, разбросанные по коду, конфигурациям и чатам без единого контроля.

Как проверить

  1. Секреты приложений хранятся в Vault, а не в коде, переменных окружения без контроля или текстовых файлах.
  2. У каждого приложения отдельная политика с минимально необходимым доступом, не общий корневой токен.
  3. Токены ограничены по времени жизни там, где это применимо к характеру сервиса.
  4. Аудит-лог включён и доступен для разбора при инциденте.

Источники

  • Методика оценки уровня зрелости кибербезопасности компании, Группа Сбер: sberbank.ru.
  • Документация HashiCorp Vault: developer.hashicorp.com.

Комментарии закрыты.