Перейти к содержанию

KV версия 2

Механизм секретов kv используется для хранения произвольных секретов в пределах хранилища Stronghold.

Имена ключей всегда должны быть строками. Если вы записываете нестроковые значения напрямую через CLI, они будут преобразованы в строки. Однако вы можете сохранить нестроковые значения, записав пары ключ/значение из JSON-файла или используя HTTP API.

Этот механизм секретов учитывает различие между операциями create и update в ACL-политиках. Также поддерживается функция patch, которая используется для выполнения частичных обновлений, в то время во время операции update выполняется полная перезапись.

Настройка

Большинство механизмов секретов должны быть предварительно настроены. Настройка обычно выполняются оператором или с помошью инструментов управления конфигурацией, таких как Terraform.

Механизам секретов v2 kv может быть включен с помощью команды:

d8 stronghold secrets enable -version=2 kv

Или вы можете передать kv-v2 в качестве типа механизма секретов:

d8 stronghold secrets enable kv-v2

Обновление с версии 1 на версию 2

Существующее хранилище kv версии 1 можно обновить до хранилища kv версии 2 с помощью CLI или API. Во время процесса миграции хранилище будет недоступно. Это может занять много времени, поэтому планируйте обновление заранее.

После обновления до версии 2 прежние пути, по которым можно было получить доступ к данным, больше не будут доступны. Вам нужно будет по новому настроить политики пользователей, чтобы восстановить доступ, как это описано в разделе Правила ACL. Аналогично, пользователям/приложениям необходимо будет обновить пути, по которым они взаимодействуют с данными kv после их обновления до версии 2.

Существующее хранилище kv версии 1 можно обновить до хранилища kv версии 2 с помощью команды CLI:

$ d8 stronghold kv enable-versioning secret/
Success! Tuned the secrets engine at: secret/

Правила ACL

Хранилище kv версии 2 использует API с префиксом, который отличается от API версии 1. Перед обновлением с версии 1 kv необходимо изменить правила ACL. Кроме того, различные пути в API версии 2 могут быть по-разному защищены ACL.

Пути для операций чтения и записи имеют префикс data/. Например, следующую политику для kv-v1:

path "secret/dev/team-1/*" {
  capabilities = ["create", "update", "read"]
}

Нужно заменить на:

path "secret/data/dev/team-1/*" {
  capabilities = ["create", "update", "read"]
}

Для kv-v2 существуют различные уровни удаления данных. Чтобы предоставить права на удаление последней версии ключа создайте такую политику:

path "secret/data/dev/team-1/*" {
  capabilities = ["delete"]
}

Чтобы разрешить удалять любую версию ключа:

path "secret/delete/dev/team-1/*" {
  capabilities = ["update"]
}

Чтобы разрешить восстанавливать удаленные версии:

path "secret/undelete/dev/team-1/*" {
  capabilities = ["update"]
}

Чтобы разрешить уничтожить значения ключей (без возможности восстановления):

path "secret/destroy/dev/team-1/*" {
  capabilities = ["update"]
}

Это политика, позволяющая получить список ключей:

path "secret/metadata/dev/team-1/*" {
  capabilities = ["list"]
}

Политика, позволяющая просматривать метаданные ключей:

path "secret/metadata/dev/team-1/*" {
  capabilities = ["read"]
}

Разрешить навсегда удалить все версии и метаданные ключа:

path "secret/metadata/dev/team-1/*" {
  capabilities = ["delete"]
}

Поля allowed_parameters, denied_parameters и required_parameters не поддерживаются для политик, используемых с хранилищем kv версии 2. Описание этих параметров см. в разделе Политики.

Использование

После того как механизм секретов включен и у пользователя/машины есть токен Stronghold с соответствующими правами, он может взаимдействовать с секретами. Синтаксис KV-v1, похожий на путь для ссылки на секрет (secret/foo), по-прежнему можно использовать в KV-v2, но мы рекомендуем использовать синтаксис с флагом -mount=secret, чтобы не перепутать его с реальным путем к секрету (реальный путь - secret/data/foo).

Запись/чтение произвольных данных

Запись ключей:

$ d8 stronghold kv put -mount=secret my-secret foo=a bar=b
Key              Value
---              -----
created_time     2024-06-19T17:20:22.985303Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          1

Чтение ключей:

$ d8 stronghold kv get -mount=secret my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2024-06-19T17:20:22.985303Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          1

====== Data ======
Key         Value
---         -----
foo         a
bar         b
   ```

- Запишите другую версию, при этом предыдущая версия будет по-прежнему доступна. Опционально может быть передан флаг `-cas` (`check-and-set)` для выполнения проверки, что ключ существует . Если флаг не установлен, запись будет разрешена. Если же флаг `cas` установленЮ, то для того чтобы запись была успешной, его значение должно соответствовать текущуей версию секрета. Если установлено значение 0, запись будет разрешена только в том случае, если ключ не существует, так как неустановленные ключи не имеют информации о версии. Также помните, что удаление "версии" не удаляет из хранилища исформацию о версиях. Таким образом, для записи в секрет, у которого были удаленные версии, параметр cas должен соответствовать текущей версии секрета.

```shell-session
$ d8 stronghold kv put -mount=secret -cas=1 my-secret foo=aa bar=bb
Key              Value
---              -----
created_time     2024-06-19T17:22:23.369372Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          2

Чтение вернет самую свежую версию данных:

$ d8 stronghold kv get -mount=secret my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2024-06-19T17:22:23.369372Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          2

====== Data ======
Key         Value
---         -----
foo         aa
bar         bb

С помощью команды d8 stronghold kv patch может быть выполнено частичное обновление секрета. Команда первоначально попытается выполнить HTTP-запрос PATCH, который требует наличия ACL-возможности patch. Запрос PATCH будет неудачным, если используемый токен связан с политикой, которая не содержит возможности patch. В этом случае команда выполнит чтение, локальное обновление и последующую запись, для которых требуются возможности ACL read и update. Опционально может быть передан флаг -cas для выполнения проверки, что ключ существует. Он будет использоваться только в случае начального запроса PATCH. Вариант с последовательными чтением и записью будет использовать значение version из секрета, возвращенного при чтении, для выполнения проверки cas при последующей записи.

$ d8 stronghold kv patch -mount=secret -cas=2 my-secret bar=bbb
Key              Value
---              -----
created_time     2024-06-19T17:23:49.199802Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          3

  ```

Команда `d8 stronghold kv patch` также поддерживает флаг `-method`, который можно использовать чтобы указать, какой метод использовать, `patch` или `rw`.

Выполнить обновление секрета используя `patch`:

```shell-session
$ d8 stronghold kv patch -mount=secret -method=patch -cas=2 my-secret bar=bbb
Key              Value
---              -----
created_time     2024-06-19T17:23:49.199802Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          3

Выполнить обновление, используя rw, то есть сначала прочитать значение, а потом записать новую измененную версию:

$ d8 stronghold kv patch -mount=secret -method=rw my-secret bar=bbb
Key              Value
---              -----
created_time     2024-06-19T17:23:49.199802Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          3

Чтение вернет самую новую версию, в которой были обновлены только заданные значения:

$ d8 stronghold kv get -mount=secret my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2024-06-19T17:23:49.199802Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          3

====== Data ======
Key         Value
---         -----
foo         aa
bar         bbb

Предыдущие врерсии секретов можно получить используя флаг -version:

$ d8 stronghold kv get -mount=secret -version=1 my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2024-06-19T17:20:22.985303Z
custom_metadata  <nil>
deletion_time    n/a
destroyed        false
version          1

====== Data ======
Key         Value
---         -----
foo         a
bar         b

Также вы можете использовать [политику генерации паролей] чтобы создавать секреты.

Создать политику:

$ d8 stronghold write sys/policies/password/example policy=-<<EOF

  length=20

  rule "charset" {
    charset = "abcdefghij0123456789"
    min-chars = 1
  }

  rule "charset" {
    charset = "!@#$%^&*STUVWXYZ"
    min-chars = 1
  }

EOF
   ```

Создать секрет, используя политику `example`:

```shell-session
$ d8 stronghold kv put -mount=secret my-generated-secret \
    password=$(d8 stronghold read -field password sys/policies/password/example/generate)
========= Secret Path =========
secret/data/my-generated-secret

======= Metadata =======
Key                Value
---                -----
created_time       2024-06-10T14:32:32.37354939Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

Прочитать созданный секрет:

$ d8 stronghold kv get -mount=secret my-generated-secret
========= Secret Path =========
secret/data/my-generated-secret

======= Metadata =======
Key                Value
---                -----
created_time       2024-06-10T14:32:32.37354939Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

====== Data ======
Key         Value
---         -----
password    !hh&be1e4j16dVc0ggae

Удаление (delete) и уничтожение (destroy) секретов

При удалении команда d8 stronghold kv delete будет выполнять «мягкое» удаление. Она пометит версию как удаленную и заполнит значение deletion_time в метаданных секрета. Мягкое удаление не удаляет данные версии из хранилища, и секрет можно восстановить с помощью команды d8 stronghold kv undelete.

Версия секрета удаляется навсегда только в том случае, если секрета имеет больше версий, чем разрешено настройкой max-versions, или при использовании команды d8 stronghold kv destroy. При использовании команды destroy данные версии будут удалены, а метаданные будут помечены как уничтоженные. Если версия очищена из-за превышения количества версий, метаданные версии также будут удалены.

Примеры:

Последняя версия ключа может быть удалена с помощью команды delete, которая также принимает флаг -versions для удаления предыдущих версий:

 $ d8 stronghold kv delete -mount=secret my-secret
 Success! Data deleted (if it existed) at: secret/data/my-secret

Версии могут быть восстановлены:

 $ d8 stronghold kv undelete -mount=secret -versions=2 my-secret
 Success! Data written to: secret/undelete/my-secret

 $ d8 stronghold kv get -mount=secret my-secret
 ====== Metadata ======
 Key              Value
 ---              -----
 created_time     2024-06-19T17:23:21.834403Z
 custom_metadata  <nil>
 deletion_time    n/a
 destroyed        false
 version          2

 ====== Data ======
 Key         Value
 ---         -----
 my-value    short-lived-s3cr3t

Уничтожение версии полностью удаляет все данные:

$ d8 stronghold kv destroy -mount=secret -versions=2 my-secret
Success! Data written to: secret/destroy/my-secret

Метаданные

Все версии и метаданные ключа можно посмотеть с помощью команды metadata или с помощью API. Удаление ключа metadata приведет к тому, что все метаданные и версии для этого ключа будут удалены навсегда.

Примеры:

Можно просмотреть все метаданные и версии для ключа:

$ d8 stronghold kv metadata get -mount=secret my-secret
========== Metadata ==========
Key                     Value
---                     -----
cas_required            false
created_time            2024-06-19T17:20:22.985303Z
current_version         2
custom_metadata         <nil>
delete_version_after    0s
max_versions            0
oldest_version          0
updated_time            2024-06-19T17:22:23.369372Z

====== Version 1 ======
Key              Value
---              -----
created_time     2024-06-19T17:20:22.985303Z
deletion_time    n/a
destroyed        false

====== Version 2 ======
Key              Value
---              -----
created_time     2024-06-19T17:22:23.369372Z
deletion_time    n/a
destroyed        true

Можно настроить параметры:

$ d8 stronghold kv metadata put -mount=secret -max-versions 2 -delete-version-after="3h25m19s" my-secret
Success! Data written to: secret/metadata/my-secret

Настройка delete-version-after будет применяться только к новым версиям, параметр max-versions будет применен при следующей операции записи.

$ d8 stronghold kv put -mount=secret my-secret my-value=newer-s3cr3t
Key              Value
---              -----
created_time     2024-06-19T17:31:16.662563Z
custom_metadata  <nil>
deletion_time    2024-06-19T20:56:35.662563Z
destroyed        false
version          4

Если у ключа больше версий, чем max-versionsб самые старые версии уничтожаются:

$ d8 stronghold kv metadata get -mount=secret my-secret
========== Metadata ==========
Key                     Value
---                     -----
cas_required            false
created_time            2024-06-19T17:20:22.985303Z
current_version         4
custom_metadata         <nil>
delete_version_after    3h25m19s
max_versions            2
oldest_version          3
updated_time            2024-06-19T17:31:16.662563Z

====== Version 3 ======
Key              Value
---              -----
created_time     2024-06-19T17:23:21.834403Z
deletion_time    n/a
destroyed        true

====== Version 4 ======
Key              Value
---              -----
created_time     2024-06-19T17:31:16.662563Z
deletion_time    2024-06-19T20:56:35.662563Z
destroyed        false

Метаданные ключа секрета могут содержать пользовательские метаданные, используемые для описания секрета, в виде пар ключ-значение. Флаг -custom-metadata можно указать несколько раз, чтобы добавить несколько пар ключ-значение.

Команда d8 stronghold kv metadata put может быть использована для полной перезаписи значения custom_metadata:

$ d8 stronghold kv metadata put -mount=secret -custom-metadata=foo=abc -custom-metadata=bar=123 my-secret
Success! Data written to: secret/metadata/my-secret

$ d8 stronghold kv get -mount=secret my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2024-06-19T17:22:23.369372Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          2

====== Data ======
Key         Value
---         -----
foo         aa
bar         bb

Команда d8 stronghold kv metadata patch может быть использована для частичной перезаписи значения custom_metadata. Следующий вызов обновит поле custom_metadata foo, но оставит bar нетронутым:

$ d8 stronghold kv metadata patch -mount=secret -custom-metadata=foo=def my-secret
Success! Data written to: secret/metadata/my-secret
$ d8 stronghold kv get -mount=secret my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2024-06-19T17:22:23.369372Z
custom_metadata  map[bar:123 foo:def]
deletion_time    n/a
destroyed        false
version          2

====== Data ======
Key         Value
---         -----
foo         aa
bar         bb

Полное уничтожение всех метаданных и версий для ключа:

$ d8 stronghold kv metadata delete -mount=secret my-secret
Success! Data deleted (if it existed) at: secret/metadata/my-secret