CoursesVault from dev to productionKV v2 versioning and check-and-set

KV v2 versioning and check-and-set

Static secrets without stampeding them.

In short. Not every secret can be dynamic. Third-party API keys, partner credentials, and some legacy systems still need a stored value.

Intermediate25 min · lesson 6 of 13

Not every secret can be dynamic. Third-party API keys, partner credentials, and some legacy systems still need a stored value. KV version 2 is Vault's versioned key-value store: every write creates a new version, deletes are soft by default, and check-and-set (CAS) prevents two operators from blindly overwriting each other.

Teams treat KV like a shared folder and then wonder why a rollback is impossible or why a deleted key still haunts them. Versioning is the feature; discipline is still required — short policies, no world-readable mounts, and rotation notes in metadata.

Enable KV v2 and write versions

Fresh Vault installs often mount secret/ as KV v2 already. If you enable it yourself, set -version=2. Writes go to .../data/.... Reads can pin ?version=N. Metadata endpoints show version history and custom metadata fields useful for ownership (owner=payments-team, rotate_after=2026-10-01).

terminal
vault secrets enable -path=secret kv-v2
vault kv put secret/payments/stripe api_key=sk_live_example
vault kv put secret/payments/stripe api_key=sk_live_rotated
vault kv get -version=1 secret/payments/stripe
vault kv metadata get secret/payments/stripe
output
====== Data ======
api_key sk_live_example
versions
0 1 2
... current_version=2

Check-and-set and safe deletes

CAS uses the current version as a precondition: vault kv put -cas=2 ... fails if version 2 is no longer latest. That stops silent clobbering during dual-admin edits. Soft delete marks versions deleted without destroying data; destroy and metadata delete are the irreversible steps. Know which one your runbook means by "delete."

KV v2 write lifecycle
1Write vN
new version created
2Read current
default gets latest undeleted
3Soft delete
version hidden, recoverable
4Destroy
version data gone for good
Soft delete is an operational seatbelt; destroy is a compliance action — require dual control for destroy in prod.

What KV is not

KV does not mint database users, does not rotate cloud keys by itself, and does not replace PKI. If a credential can be dynamic, prefer the database/cloud engines. Use KV for truly static material, keep TTLs on the wrapping tokens that deliver it, and audit every read. Pair with Vault Agent so apps read a file refreshed from KV instead of long-lived env vars copied everywhere.

Version history is still sensitive
Old versions may contain previous live keys. Destroy superseded versions after rotation when policy requires, and restrict metadata/list tightly.

Going deeper

Versioning also changes incident response. When someone writes the wrong API key, you can read the previous version, restore it deliberately with CAS awareness, and destroy the bad version after you confirm no consumer still needs it. That is a different operational muscle than "overwrite the file in the password manager and hope."

Custom metadata fields are underrated. Put owner, ticket, and rotate_after on the secret metadata so automation and humans share one inventory without a second spreadsheet. Policies can still deny metadata writes to app roles while allowing data reads — split those capabilities consciously.

Replication and DR apply to KV like anything else in raft: a restored snapshot restores versions. Practice reading an old version after restore so you know whether your runbooks assume soft-deleted versions survive. Document destroy as a deliberate compliance action with dual control, not a casual cleanup.

Try this

Write two versions, read version 1 explicitly, soft-delete, confirm current read fails, then undelete.

terminal
vault kv put secret/lab/demo password=one
vault kv put secret/lab/demo password=two
vault kv get -version=1 secret/lab/demo
vault kv delete secret/lab/demo
vault kv get secret/lab/demo || true
vault kv undelete -versions=2 secret/lab/demo
vault kv get secret/lab/demo
output
password one
Error: ... version has been deleted
password two
# SUCCESS — soft delete + undelete loop

Takeaway

KV v2 gives versioned static secrets with CAS and deliberate delete semantics. Use it sparingly, policy it tightly, and prefer dynamic engines when the dependency allows.

Next: dynamic database and cloud credentials — secrets that expire without a calendar invite.

Quick check
01Check-and-set (-cas) prevents…
Incorrect — Unrelated to KV concurrency.
Correct — CAS makes concurrent writes fail safely.
Incorrect — Audit still records writes.
Incorrect — CAS is about put preconditions.
02After vault kv delete on v2…
Incorrect — Default delete is soft; destroy is separate.
Correct — Correct unless you destroy.
Incorrect — Mount disable is a different operation.
Incorrect — Nonsense.

Related