KV v2: версии секретов

Почему второй версии KV-движка хватает «машины времени» для секретов и как ей пользоваться.

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

Статический секрет меняется со временем: ротация пароля, новый ключ API. В KV v1 новое значение просто затирало старое. KV v2 хранит историю, что бесценно при ошибочной записи или для расследования инцидента.

Версии при каждой записи

Каждый kv put создаёт новую версию, не удаляя предыдущую:

vault kv put secret/myapp/token value="v1-token"   # version 1
vault kv put secret/myapp/token value="v2-token"   # version 2
vault kv put secret/myapp/token value="v3-token"   # version 3

По умолчанию kv get отдаёт последнюю версию, но можно запросить любую:

vault kv get -version=1 secret/myapp/token

Метаданные и история

vault kv metadata get secret/myapp/token
======= Metadata =======
Key                Value
---                -----
current_version    3
max_versions       0

====== Version 1 ======  created_time ... 
====== Version 2 ======  created_time ... 
====== Version 3 ======  created_time ... 

Три уровня удаления

KV v2 различает три операции удаления — от мягкой к необратимой:

КомандаЧто делает
kv deletesoft delete: помечает версию удалённой, данные ещё восстановимы
kv undeleteвозвращает мягко удалённую версию
kv destroyнеобратимо стирает данные конкретной версии
kv metadata deleteудаляет путь со всей историей
# мягко удалить версию 2
vault kv delete -versions=2 secret/myapp/token

# передумали — вернуть
vault kv undelete -versions=2 secret/myapp/token

# стереть навсегда
vault kv destroy -versions=2 secret/myapp/token

Как работает под капотом

Из-за версионирования KV v2 раскладывает данные по двум подпутям: secret/data/... для значений и secret/metadata/... для истории. Именно поэтому в API и политиках путь к секрету выглядит как secret/data/myapp/token, хотя в CLI вы пишете просто secret/myapp/token — CLI добавляет data/ сам. Это частая причина ошибок в политиках.

Ограничение числа версий

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

vault kv metadata put -max-versions=5 secret/myapp/token

Частые ошибки

  • Путать delete и destroy — delete обратим, destroy нет.
  • Забыть про data/ в политике — путь secret/myapp/* в политике не даст доступа к secret/data/myapp/*.
  • Считать, что delete освобождает место — данные остаются до destroy.

Итог

  • KV v2 хранит историю версий: можно читать прежние значения и откатываться.
  • Удаление многоуровневое: delete (обратимо) → undelete → destroy (навсегда).
  • В API/политиках путь содержит data/ (secret/data/...), хотя CLI это скрывает.
Проверьте себя
1. Чем delete отличается от destroy в KV v2?
AНичем
Bdelete — мягкое удаление (обратимо через undelete), destroy — необратимое стирание
Cdestroy обратим, delete нет
DОба удаляют всю историю
2. Почему путь к секрету в политике пишут как secret/data/myapp, а в CLI — secret/myapp?
AЭто опечатка в документации
BKV v2 хранит значения под подпутём data; CLI добавляет его автоматически
Cdata — обязательное имя любого секрета
DВ CLI путь всегда короче на одно слово
3. Что произойдёт, если задать max_versions=5 и записать шестую версию?
AЗапись будет отклонена
BСамая старая версия будет вытеснена
CВсе версии удалятся
DVault выдаст ошибку