Перейти к основному содержимому

Введение в Spring Cloud Vault

· 6 мин. чтения

1. Обзор

В этом руководстве мы покажем, как мы можем использовать хранилище Hashicorp в приложениях Spring Boot для защиты конфиденциальных данных конфигурации.

Мы предполагаем, что у нас есть некоторое знание Vault и что у нас уже есть тестовая установка . Если это не так, давайте на минутку прочитаем наш учебник Vault Intro , чтобы мы могли познакомиться с его основами.

2. Весеннее облачное хранилище

Spring Cloud Vault является относительно недавним дополнением к стеку Spring Cloud, которое позволяет приложениям получать доступ к секретам, хранящимся в экземпляре Vault, прозрачным способом .

В целом переход на Vault — очень простой процесс: просто добавьте необходимые библиотеки и добавьте несколько дополнительных свойств конфигурации в наш проект, и все готово. Никаких изменений кода не требуется!

Это возможно, потому что он действует как PropertySource с высоким приоритетом, зарегистрированный в текущей среде .

Таким образом, Spring будет использовать его всякий раз, когда требуется свойство. Примеры включают свойства DataSource , ConfigurationProperties и т. д.

3. Добавление Spring Cloud Vault в проект Spring Boot

Чтобы включить библиотеку spring-cloud-vault в проект Spring Boot на основе Maven, мы используем связанный начальный артефакт, который вытянет все необходимые зависимости.

Помимо основного стартера, мы также включим spring-vault-config-databases , который добавляет поддержку динамических учетных данных базы данных:

<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-vault-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-vault-config-databases</artifactId>
</dependency>

Последнюю версию стартового Spring Cloud Vault можно загрузить с Maven Central.

3.1. Базовая конфигурация

Для правильной работы Spring Cloud Vault нужен способ определить, где связаться с сервером Vault и как аутентифицироваться на нем.

Мы делаем это, предоставляя необходимую информацию в application.yml или application.properties :

spring:
cloud:
vault:
uri: https://localhost:8200
ssl:
trust-store: classpath:/vault.jks
trust-store-password: changeit
config:
import: vault://

Свойство spring.cloud.vault.uri указывает на адрес API Vault. Поскольку наша тестовая среда использует HTTPS с самозаверяющим сертификатом, нам также необходимо предоставить хранилище ключей, содержащее его открытый ключ.

Обратите внимание, что эта конфигурация не имеет данных аутентификации . В простейшем случае, когда мы используем фиксированный токен, мы можем передать его через системное свойство spring.cloud.vault.token или переменную среды. Этот подход хорошо работает в сочетании со стандартными механизмами облачной конфигурации, такими как ConfigMaps или секреты Docker Kubernetes.

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

4. Использование бэкэнда Generic Secrets

Мы используем бэкэнд Generic Secret для доступа к неверсионным секретам, хранящимся в виде пар ключ-значение в Vault .

Предполагая, что у нас уже есть зависимость spring-cloud-starter-vault-config в нашем пути к классам , все, что нам нужно сделать, это добавить несколько свойств в файл application.yml :

spring:
cloud:
vault:
# other vault properties omitted ...
generic:
enabled: true
application-name: fakebank

В этом случае свойство application-name является необязательным. Если не указано, Spring вместо этого примет значение стандартного spring.application.name .

Теперь мы можем использовать все пары ключ/значение, хранящиеся в secret/fakebank , как любое другое свойство среды . Следующий фрагмент показывает, как мы можем прочитать значение ключа foo , хранящегося по этому пути:

@Autowired Environment env;
public String getFoo() {
return env.getProperty("foo");
}

Как мы видим, сам код ничего не знает о Vault, и это хорошо! Мы по-прежнему можем использовать фиксированные свойства в локальных тестах и переключаться на Vault по своему усмотрению, просто включив одно свойство в приложении .yml .

4.1. Примечание о профилях Spring

Если доступно в текущей среде, Spring Cloud Vault будет использовать доступные имена профилей в качестве суффикса, добавленного к указанному базовому пути, по которому будет выполняться поиск пар ключ/значение .

Он также будет искать свойства в настраиваемом пути к приложению по умолчанию (с суффиксом профиля и без него), чтобы мы могли иметь общие секреты в одном месте. Используйте эту функцию с осторожностью!

Подводя итог, можно сказать, что если рабочий профиль нашего приложения fakebank активен , Spring Vault будет искать свойства, хранящиеся по следующим путям: ``

  1. секрет/ фейкбанк /производство (более высокий приоритет)
  2. секретный / поддельный банк
  3. секрет/применение/производство
  4. секрет/приложение (более низкий приоритет)

В предыдущем списке приложение — это имя, которое Spring использует в качестве дополнительного местоположения по умолчанию для секретов. Мы можем изменить его, используя свойство spring.cloud.vault.generic.default-context .

Свойства, хранящиеся по наиболее конкретному пути, будут иметь приоритет над остальными. Например, если одно и то же свойство foo доступно по указанным выше путям, порядок приоритета будет следующим:

5. Использование базы данных Secret Backend

Базовый модуль базы данных позволяет приложениям Spring использовать динамически генерируемые учетные данные базы данных, созданные Vault . Spring Vault внедряет эти учетные данные в стандартные свойства spring.datasource.username и spring.datasource.password , чтобы их можно было выбрать с помощью обычных DataSource s.

Обратите внимание, что перед использованием этого бэкенда мы должны создать конфигурацию базы данных и роли в Vault, как описано в нашем предыдущем руководстве .

Чтобы использовать учетные данные базы данных, сгенерированные Vault, в нашем приложении Spring, базы данных spring-cloud-vault-config-database должны присутствовать в пути к классам проекта вместе с соответствующим драйвером JDBC.

Нам также нужно включить его использование в нашем приложении, добавив несколько свойств в наш application.yml:

spring:
cloud:
vault:
# ... other properties omitted
database:
enabled: true
role: fakebank-accounts-rw

Наиболее важным свойством здесь является свойство роли , которое содержит имя роли базы данных, хранящееся в Vault. Во время запуска Spring свяжется с Vault и запросит создание новых учетных данных с соответствующими привилегиями.

Хранилище по умолчанию аннулирует привилегии, связанные с этими учетными данными, по истечении настроенного срока жизни.

К счастью, Spring Vault автоматически продлит аренду, связанную с полученными учетными данными. При этом учетные данные будут оставаться действительными, пока работает наше приложение.

Теперь давайте посмотрим на эту интеграцию в действии. Следующий фрагмент получает новое подключение к базе данных из источника данных, управляемого Spring :

Connection c = datasource.getConnection();

И снова мы видим, что в нашем коде нет никаких признаков использования Vault . Вся интеграция происходит на уровне среды , поэтому наш код можно легко протестировать, как обычно.

6. Заключение

В этом руководстве мы показали, как интегрировать Vault с Spring Boot с помощью библиотеки Spring Vault. Мы рассмотрели два распространенных случая использования: общие пары ключ/значение и учетные данные динамической базы данных.

Пример проекта, содержащий все необходимые зависимости, тесты интеграции и сценарии установки хранилища, доступен на GitHub .