1. Обзор
В этом руководстве мы рассмотрим хранилище Hashicorp — популярный инструмент, используемый для безопасного управления конфиденциальной информацией в современных архитектурах приложений .
Основные темы, которые мы рассмотрим, включают:
- Какую проблему Vault пытается решить
- Архитектура Vault и основные концепции
- Настройка простой тестовой среды
- Взаимодействие с Vault с помощью инструмента командной строки
2. Проблема с конфиденциальной информацией
Прежде чем углубляться в Vault, давайте попробуем понять проблему, которую оно пытается решить: управление конфиденциальной информацией.
Большинству приложений для правильной работы требуется доступ к конфиденциальным данным . Например, приложение электронной коммерции может где-то настроить имя пользователя/пароль для подключения к своей базе данных. Также могут потребоваться ключи API для интеграции с другими поставщиками услуг, такими как платежные шлюзы, логистика и другие деловые партнеры.
Учетные данные базы данных и ключи API — это некоторые примеры конфиденциальной информации, которую нам необходимо хранить и делать доступной для наших приложений безопасным способом.
Простое решение — сохранить эти учетные данные в файле конфигурации и прочитать их во время запуска. Однако проблема с этим подходом очевидна. Тот, у кого есть доступ к этому файлу, пользуется теми же привилегиями базы данных, что и наше приложение, — обычно предоставляя ему полный доступ ко всем сохраненным данным.
Мы можем попытаться немного усложнить задачу, зашифровав эти файлы. Однако такой подход мало что добавит с точки зрения общей безопасности. В основном потому, что наше приложение должно иметь доступ к мастер-ключу. Шифрование, используемое таким образом, создаст только «ложное» ощущение безопасности.
Современные приложения и облачные среды, как правило, добавляют дополнительную сложность: распределенные службы, несколько баз данных, системы обмена сообщениями и т. д. — все они содержат конфиденциальную информацию, распространяемую повсюду, что увеличивает риск нарушения безопасности.
Так что мы можем сделать? Давайте Хранилище это!
3. Что такое хранилище?
Hashicorp Vault решает проблему управления конфиденциальной информацией — секретом
на языке Vault. «Управление» в этом контексте означает, что Сейф контролирует все аспекты конфиденциальной информации : ее создание, хранение, использование и, что не менее важно, ее отзыв.
Hashicorp предлагает две версии Vault. Версия с открытым исходным кодом, используемая в этой статье, может использоваться бесплатно даже в коммерческих средах. Также доступна платная версия, которая включает техническую поддержку по различным SLA и дополнительные функции, такие как поддержка HSM (Hardware Security Module).
3.1. Архитектура и ключевые особенности
Архитектура Vault обманчиво проста. Его основными компонентами являются:
- Бэкэнд постоянства — хранилище для всех секретов
- Сервер API, который обрабатывает запросы клиентов и выполняет операции с секретами.
- Количество
секретных механизмов,
по одному для каждого типа поддерживаемого секретного типа.
Делегируя всю обработку секретов Vault, мы можем смягчить некоторые проблемы безопасности:
- Нашим приложениям больше не нужно их хранить — просто запросите Vault, когда это необходимо, и откажитесь от него.
- Мы можем использовать недолговечные секреты, тем самым ограничивая «окно возможностей», когда злоумышленник может использовать украденный секрет.
Сейф шифрует все данные с помощью ключа шифрования перед записью в хранилище. Этот ключ шифрования зашифрован еще одним ключом — мастер-ключом, который используется только при запуске.
Ключевым моментом в реализации Vault является то, что он не хранит главный ключ на сервере. Это означает, что даже Vault не может получить доступ к своим сохраненным данным после запуска. В этот момент говорят, что экземпляр Vault находится в «запечатанном» состоянии.
Позже мы рассмотрим шаги, необходимые для создания главного ключа и распечатывания экземпляра Vault.
После распечатывания Vault будет готов принимать запросы API. Эти запросы, конечно же, требуют аутентификации, что подводит нас к тому, как Vault аутентифицирует клиентов и решает, что они могут или не могут делать.
3.2. Аутентификация
Для доступа к секретам в Vault клиенту необходимо пройти аутентификацию одним из поддерживаемых методов . В самом простом методе используются токены, которые представляют собой просто строки, отправляемые при каждом запросе API с использованием специального заголовка HTTP.
При первоначальной установке Vault автоматически генерирует «корневой токен». Этот токен эквивалентен привилегированному суперпользователю в системах Linux, поэтому его использование должно быть сведено к минимуму. Лучше всего использовать этот корневой токен только для создания других токенов с меньшими привилегиями, а затем отозвать его. Однако это не проблема, так как позже мы можем сгенерировать другой корневой токен, используя распечатанные ключи.
Vault также поддерживает другие механизмы аутентификации, такие как LDAP, JWT, сертификаты TLS и другие. Все эти механизмы основаны на базовом механизме токенов: как только Vault проверит наш клиент, он предоставит токен, который мы затем сможем использовать для доступа к другим API.
Токены имеют несколько связанных с ними свойств. Основные свойства:
- Набор связанных
политик
(см. следующий раздел) - Время жить
- Можно ли его продлить
- Максимальное количество использований
Если не указано иное, токены, созданные Vault, образуют отношения родитель-потомок. Дочерний токен может иметь не более того же уровня привилегий, что и родительский.
Обратное неверно: мы можем — и обычно делаем — создать дочерний токен с ограничительными политиками. Еще один ключевой момент в отношении этих отношений: когда мы делаем недействительным токен, все дочерние токены и их потомки также становятся недействительными .
3.3. Политики
Политики точно определяют, к каким секретам клиент может получить доступ и какие операции он может с ними выполнять . Давайте посмотрим, как выглядит простая политика:
path "secret/accounting" {
capabilities = [ "read" ]
}
Здесь мы использовали синтаксис HCL (язык конфигурации Hashicorp) для определения нашей политики. Vault также поддерживает JSON для этой цели, но в наших примерах мы будем придерживаться HCL, так как его легче читать.
Политики в Vault «по умолчанию запрещены» . Токен, прикрепленный к этому образцу политики, получит доступ к секретам, хранящимся в разделе секрет/учет
, и ни к чему другому. Во время создания токен можно прикрепить к нескольким политикам. Это очень полезно, поскольку позволяет нам создавать и тестировать меньшие политики, а затем применять их по мере необходимости.
Еще одним важным аспектом политик является то, что они используют ленивую оценку. Это означает, что мы можем обновить данную политику, и все токены будут затронуты немедленно.
Политики, описанные до сих пор, также называются политиками списка управления доступом или политиками ACL. Vault также поддерживает два дополнительных типа политик: политики EGP и RGP. Они доступны только в платных версиях и расширяют базовый синтаксис политики за счет поддержки Sentinel .
Когда это возможно, это позволяет нам учитывать в наших политиках дополнительные атрибуты, такие как время суток, несколько факторов аутентификации, происхождение клиентской сети и т. д. Например, мы можем определить политику, которая разрешает доступ к данному секрету только в рабочее время.
Мы можем найти более подробную информацию о синтаксисе политики в документации Vault .
4. Секретные типы
Vault поддерживает ряд различных типов секретов, которые подходят для разных вариантов использования:
Ключ-значение:
простые статические пары ключ-значениеДинамически генерируемые учетные данные
: генерируются Vault по запросу клиента.Криптографические ключи
: используются для выполнения криптографических функций с данными клиента.
Каждый тип секрета определяется следующими атрибутами:
- Точка
монтирования
,
определяющая префикс REST API . - Набор операций, предоставляемых через соответствующий API
- Набор параметров конфигурации
Данный секретный экземпляр доступен через путь
, очень похожий на дерево каталогов в файловой системе. Первый компонент этого пути соответствует точке монтирования,
где находятся все секреты этого типа .
Например, строка secret/my-application
соответствует пути, по которому мы можем найти пары ключ-значение для my-application
.
4.1. Секреты ключ-значение
Секреты ключ-значение, как следует из названия, представляют собой простые пары, доступные по заданному пути . Например, мы можем хранить пару foo=bar
по пути /secret/my-application.
Позже мы используем тот же путь для извлечения одной или нескольких пар — несколько пар могут храниться по одному и тому же пути.
Vault поддерживает три типа секретов Key-Value:
Неверсионные пары ключей
, где обновления заменяют существующие значения.Версионные пары ключей,
которые поддерживают настраиваемое количество старых версий.Cubbyhole
, особый тип пар ключей без контроля версий, значения которых ограничены заданнымтокеном доступа
(подробнее об этом позже).
Секреты типа «ключ-значение» являются статическими по своей природе, поэтому для них не существует концепции связанного с ними срока действия. Основным вариантом использования такого секрета является хранение учетных данных для доступа к внешним системам, например ключей API.
В таких сценариях обновление учетных данных представляет собой полуавтоматический процесс, обычно требующий, чтобы кто-то получил новые учетные данные и использовал командную строку Vault или его пользовательский интерфейс для ввода новых значений.
4.2. Динамически генерируемые секреты
Динамические секреты генерируются Vault «на лету» по запросу приложения . Vault поддерживает несколько типов динамических секретов, в том числе следующие:
- Учетные данные базы данных
- Пары ключей SSH
- Сертификаты X.509
- Учетные данные AWS
- Учетные записи облачных сервисов Google
- Учетные записи Active Directory
Все они следуют одному и тому же шаблону использования. Во-первых, мы настраиваем секретный механизм с данными, необходимыми для подключения к связанной службе. Затем мы определяем одну или несколько ролей,
которые описывают фактическое создание секрета.
В качестве примера возьмем секретный движок базы данных. Во-первых, мы должны настроить Vault со всеми данными о подключениях к базе данных пользователей, включая учетные данные ранее существовавшего пользователя с правами администратора для создания новых пользователей.
Затем мы создаем одну или несколько ролей (ролей хранилища, а не ролей базы данных), содержащих фактические операторы SQL, используемые для создания нового пользователя. Обычно они включают не только оператор создания пользователя, но и все необходимые операторы предоставления
доступа, необходимые для доступа к объектам схемы (таблицам, представлениям и т. д.).
Когда клиент получает доступ к соответствующему API, Vault создаст нового временного пользователя в базе данных, используя предоставленные операторы, и вернет его учетные данные . Затем клиент может использовать эти учетные данные для доступа к базе данных в течение периода, определяемого атрибутом срока жизни запрошенной роли.
Когда срок действия учетных данных истечет, Сейф автоматически аннулирует все привилегии, связанные с этим пользователем. Клиент также может запросить у Сейфа обновление этих учетных данных. Процесс обновления произойдет только в том случае, если он поддерживается конкретным драйвером базы данных и разрешен соответствующей политикой.
4.3. Криптографические ключи
Секретные механизмы типа обрабатывают криптографические функции, такие как шифрование, дешифрование, подпись и т.д. Во всех этих операциях используются криптографические ключи, сгенерированные и сохраненные внутри Vault . Если это явно не указано, Сейф никогда не раскрывает данный криптографический ключ.
Связанный API позволяет клиентам отправлять данные Vault в виде обычного текста и получать их зашифрованную версию. Возможно и обратное: мы можем отправить зашифрованные данные и получить исходный текст.
В настоящее время существует только один двигатель этого типа: двигатель Transit
. Этот движок поддерживает популярные типы ключей, такие как RSA и ECDSA, а также поддерживает конвергентное шифрование.
При использовании этого режима данное значение открытого текста всегда приводит к одному и тому же результату зашифрованного текста, свойство, которое очень полезно в некоторых приложениях.
Например, мы можем использовать этот режим для шифрования номеров кредитных карт в таблице журнала транзакций. При конвергентном шифровании каждый раз, когда мы вставляем новую транзакцию, значение зашифрованной кредитной карты будет одинаковым, что позволяет использовать обычные SQL-запросы для отчетов, поиска и т. д.
5. Настройка хранилища
В этом разделе мы создадим локальную тестовую среду, чтобы протестировать возможности Vault.
Развертывание Vault простое: просто скачайте пакет , соответствующий нашей операционной системе, и извлеките его исполняемый файл ( vault
или vault.exe
в Windows) в какой-нибудь каталог в нашем PATH. Этот исполняемый файл содержит сервер, а также является стандартным клиентом . Также доступен официальный образ Docker , но мы не будем его здесь рассматривать.
Vault поддерживает режим разработки
, который подходит для быстрого тестирования и привыкания к его инструменту командной строки, но он слишком упрощен для реальных случаев использования: все данные теряются при перезапуске, а для доступа к API используется обычный HTTP .
Вместо этого мы будем использовать постоянное хранилище на основе файлов и настроим HTTPS, чтобы мы могли изучить некоторые детали реальной конфигурации, которые могут быть источником проблем.
5.1. Запуск сервера Vault
Vault использует файл конфигурации в формате HCL или JSON. Следующий файл определяет всю конфигурацию, необходимую для запуска нашего сервера с использованием хранилища файлов и самоподписанного сертификата:
storage "file" {
path = "./vault-data"
}
listener "tcp" {
address = "127.0.0.1:8200"
tls_cert_file = "./src/test/vault-config/localhost.cert"
tls_key_file = "./src/test/vault-config/localhost.key"
}
Теперь давайте запустим Vault. Откройте командную оболочку, перейдите в каталог, содержащий наш файл конфигурации, и выполните эту команду:
$ vault server -config ./vault-test.hcl
Vault запустится и покажет несколько сообщений об инициализации. Они будут включать его версию, некоторые детали конфигурации и адрес, по которому доступен API. Вот и все — наш сервер Vault запущен и работает.
5.2. Инициализация хранилища
Теперь наш сервер Vault запущен, но, поскольку это его первый запуск, нам нужно его инициализировать.
Давайте откроем новую оболочку и выполним для этого следующие команды:
$ export VAULT_ADDR=https://localhost:8200
$ export VAULT_CACERT=./src/test/vault-config/localhost.cert
$ vault operator init
Здесь мы определили несколько переменных среды, поэтому нам не нужно каждый раз передавать их в Vault в качестве параметров:
VAULT_ADDR
: базовый URI, по которому наш сервер API будет обслуживать запросы.VAULT_CACERT
: Путь к открытому ключу сертификата нашего сервера.
В нашем случае мы используем VAULT_CACERT
, поэтому мы можем использовать HTTPS для доступа к API Vault. Нам это нужно, потому что мы используем самозаверяющие сертификаты. В этом нет необходимости для производственных сред, где у нас обычно есть доступ к сертификатам, подписанным ЦС.
После выполнения вышеуказанной команды мы должны увидеть такое сообщение:
Unseal Key 1: <key share 1 value>
Unseal Key 2: <key share 2 value>
Unseal Key 3: <key share 3 value>
Unseal Key 4: <key share 4 value>
Unseal Key 5: <key share 5 value>
Initial Root Token: <root token value>
... more messages omitted
Пять первых строк — это общие общие ключи, которые мы позже будем использовать для вскрытия хранилища Vault. Обратите внимание, что Vault отображает общий доступ к мастер-ключу только во время инициализации — и никогда больше. Примите к сведению и сохраните их в безопасности, иначе мы потеряем доступ к нашим секретам после перезапуска сервера!
Также обратите внимание на корневой токен
, так как он понадобится нам позже. В отличие от незапечатанных ключей, корневые токены можно легко сгенерировать позднее , поэтому их безопасно уничтожить после завершения всех задач настройки. Поскольку позже мы будем вводить команды, для которых требуется токен аутентификации, давайте пока сохраним корневой токен в переменной среды:
$ export VAULT_TOKEN=<root token value> (Unix/Linux)
Давайте посмотрим на состояние нашего сервера теперь, когда мы его инициализировали, с помощью следующей команды:
$ vault status
Key Value
--- -----
Seal Type shamir
Sealed true
Total Shares 5
Threshold 3
Unseal Progress 0/3
Unseal Nonce n/a
Version 0.10.4
HA Enabled false
Мы видим, что Убежище все еще запечатано. Мы также можем следить за ходом распечатывания: «0/3» означает, что Vault нужно три доли, но пока нет ни одной. Давайте двигаться вперед и обеспечить его нашими акциями.
5.3. Распечатать хранилище
Теперь мы распечатываем Убежище, чтобы начать пользоваться его секретными службами. Нам нужно предоставить любые три из пяти ключевых акций, чтобы завершить процесс распечатывания:
$ vault operator unseal <key share 1 value>
$ vault operator unseal <key share 2 value>
$ vault operator unseal <key share 3 value>
После выполнения каждой команды хранилище будет печатать ход распечатывания, в том числе необходимое количество общих ресурсов. При отправке последнего общего ключа мы увидим такое сообщение:
Key Value
--- -----
Seal Type shamir
Sealed false
... other properties omitted
Свойство «Запечатанный» в данном случае имеет значение «false», что означает, что Vault готов принимать команды.
6. Тестирование хранилища
В этом разделе мы протестируем нашу установку Vault, используя два поддерживаемых типа секретов: ключ/значение и базу данных. Мы также покажем, как создавать новые токены с прикрепленными к ним определенными политиками.
6.1. Использование секретов ключ/значение
Во-первых, давайте сохраним секретные пары «ключ-значение» и прочитаем их. Предполагая, что командная оболочка, используемая для инициализации Vault, все еще открыта, мы используем следующую команду для сохранения этих пар по пути secret/fakebank
:
$ vault kv put secret/fakebank api_key=abc1234 api_secret=1a2b3c4d
Теперь мы можем восстановить эти пары в любое время с помощью следующей команды:
$ vault kv get secret/fakebank
======= Data =======
Key Value
--- -----
api_key abc1234
api_secret 1a2b3c4d
Этот простой тест показывает нам, что Vault работает должным образом. Теперь мы можем протестировать некоторые дополнительные функции.
6.2. Создание новых токенов
До сих пор мы использовали корневой токен для аутентификации наших запросов. Поскольку корневой токен слишком
мощный, рекомендуется использовать токены с меньшими привилегиями и более коротким временем жизни.
Давайте создадим новый токен, который мы можем использовать так же, как корневой токен, но срок его действия истечет всего через минуту:
$ vault token create -ttl 1m
Key Value
--- -----
token <token value>
token_accessor <token accessor value>
token_duration 1m
token_renewable true
token_policies ["root"]
identity_policies []
policies ["root"]
Давайте протестируем этот токен, используя его для чтения пар ключ/значение, которые мы создали ранее:
$ export VAULT_TOKEN=<token value>
$ vault kv get secret/fakebank
======= Data =======
Key Value
--- -----
api_key abc1234
api_secret 1a2b3c4d
Если мы подождем минуту и попытаемся повторить эту команду, мы получим сообщение об ошибке:
$ vault kv get secret/fakebank
Error making API request.
URL: GET https://localhost:8200/v1/sys/internal/ui/mounts/secret/fakebank
Code: 403. Errors:
* permission denied
Сообщение указывает, что наш токен больше не действителен, чего мы и ожидали.
6.3. Политики тестирования
Образец токена, который мы создали в предыдущем разделе, был недолговечным, но все же очень мощным. Давайте теперь воспользуемся политиками для создания токенов с более ограниченным доступом.
Например, давайте определим политику, которая разрешает доступ только для чтения к пути secret/fakebank
, который мы использовали ранее:
$ cat > sample-policy.hcl <<EOF
path "secret/fakebank" {
capabilities = ["read"]
}
EOF
$ export VAULT_TOKEN=<root token>
$ vault policy write fakebank-ro ./sample-policy.hcl
Success! Uploaded policy: fakebank-ro
Теперь мы создаем токен с этой политикой с помощью следующей команды:
$ export VAULT_TOKEN=<root token>
$ vault token create -policy=fakebank-ro
Key Value
--- -----
token <token value>
token_accessor <token accessor value>
token_duration 768h
token_renewable true
token_policies ["default" "fakebank-ro"]
identity_policies []
policies ["default" "fakebank-ro"]
Как мы делали раньше, давайте прочитаем наши секретные значения, используя этот токен:
$ export VAULT_TOKEN=<token value>
$ vault kv get secret/fakebank
======= Data =======
Key Value
--- -----
api_key abc1234
api_secret 1a2b3c4d
Все идет нормально. Мы можем читать данные, как и ожидалось. Давайте посмотрим, что произойдет, когда мы попытаемся обновить этот секрет:
$ vault kv put secret/fakebank api_key=foo api_secret=bar
Error writing data to secret/fakebank: Error making API request.
URL: PUT https://127.0.0.1:8200/v1/secret/fakebank
Code: 403. Errors:
* permission denied
Поскольку наша политика явно не разрешает запись, Сейф возвращает код состояния 403 — доступ запрещен.
6.4. Использование учетных данных динамической базы данных
В качестве последнего примера в этой статье давайте воспользуемся секретным механизмом базы данных Vault для создания динамических учетных данных. Здесь мы предполагаем, что у нас есть сервер MySQL, доступный локально, и что мы можем получить к нему доступ с привилегиями «root». Мы также будем использовать очень простую схему, состоящую из одной таблицы — account
.
Сценарий SQL, используемый для создания этой схемы и привилегированного пользователя, доступен здесь.
Теперь давайте настроим Vault для использования этой базы данных. Секретный механизм базы данных не включен по умолчанию, поэтому мы должны исправить это, прежде чем продолжить:
$ vault secrets enable database
Success! Enabled the database secrets engine at: database/
Теперь мы создаем ресурс конфигурации базы данных:
$ vault write database/config/mysql-fakebank \
plugin_name=mysql-legacy-database-plugin \
connection_url="{{username}}:{{password}}@tcp(127.0.0.1:3306)/fakebank" \
allowed_roles="*" \
username="fakebank-admin" \
password="Sup&rSecre7!"
Префикс пути database/config
— это место, где должны храниться все конфигурации базы данных. Мы выбираем имя mysql-fakebank
, чтобы мы могли легко выяснить, к какой базе данных относится эта конфигурация. Что касается ключей конфигурации:
plugin_name:
определяет, какой плагин базы данных будет использоваться. Доступные имена плагинов описаны в документации Vault.connection_url
: это шаблон, используемый плагином при подключении к базе данных. Обратите внимание на заполнители шаблонов {{username}} и {{password}}. При подключении к базе данных Vault заменит эти заполнители фактическими значениями.allow_roles
: определите, какие роли Vault (обсуждаемые далее) могут использовать эту конфигурацию. В нашем случае мы используем «*», поэтому он доступен для всех ролей.имя пользователя и пароль:
это учетная запись, которую Vault будет использовать для выполнения операций с базой данных, таких как создание нового пользователя и отзыв его привилегий.
Настройка роли базы данных Vault
Последняя задача настройки — создать ресурс роли базы данных Vault, содержащий команды SQL, необходимые для создания пользователя. Мы можем создать столько ролей, сколько необходимо, в соответствии с нашими требованиями безопасности.
Здесь мы создаем роль, которая предоставляет доступ только для чтения ко всем таблицам схемы fakebank
:
$ vault write database/roles/fakebank-accounts-ro \
db_name=mysql-fakebank \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';GRANT SELECT ON fakebank.* TO '{{name}}'@'%';"
Ядро базы данных определяет префикс пути к базе данных/ролям
как место для хранения ролей. fakebank-accounts-ro
— это имя роли, которое мы позже будем использовать при создании динамических учетных данных. Мы также поставляем следующие ключи:
db_name
: Имя существующей конфигурации базы данных. Соответствует последней части пути, который мы использовали при создании ресурса конфигурации.create_statements:
список шаблонов операторов SQL, которые Vault будет использовать для создания нового пользователя.
Создание динамических учетных данных
Когда у нас есть роль базы данных и ее соответствующая конфигурация, мы генерируем новые динамические учетные данные с помощью следующей команды:
$ vault read database/creds/fakebank-accounts-ro
Key Value
--- -----
lease_id database/creds/fakebank-accounts-ro/0c0a8bef-761a-2ef2-2fed-4ee4a4a076e4
lease_duration 1h
lease_renewable true
password <password>
username <username>
Префикс database/creds
используется для создания учетных данных для доступных ролей. Поскольку мы использовали роль fakebank-accounts-ro
, возвращенное имя пользователя/пароль будет ограничено для выбора
операций.
Мы можем проверить это, подключившись к базе данных, используя предоставленные учетные данные, а затем выполнив некоторые команды SQL:
$ mysql -h 127.0.0.1 -u <username> -p fakebank
Enter password:
MySQL [fakebank]> select * from account;
... omitted for brevity
2 rows in set (0.00 sec)
MySQL [fakebank]> delete from account;
ERROR 1142 (42000): DELETE command denied to user 'v-fake-9xoSKPkj1'@'localhost' for table 'account'
Мы видим, что первый выбор
выполнен успешно, но мы не можем выполнить оператор удаления
. Наконец, если мы подождем один час и попытаемся подключиться, используя те же учетные данные, мы больше не сможем подключиться к базе данных. Сейф автоматически отозвал все привилегии у этого пользователя
7. Заключение
В этой статье мы рассмотрели основы хранилища Hashicorp, в том числе некоторые сведения о проблеме, которую оно пытается решить, его архитектуру и основное использование.
Попутно мы создали простую, но функциональную тестовую среду, которую будем использовать в последующих статьях.
В следующей статье будет рассмотрен очень специфический вариант использования Vault: его использование в контексте приложения Spring Boot . Следите за обновлениями!