The kv secrets engine is used to store arbitrary secrets within the
configured physical storage for Vault.
Key names must always be strings. If you write non-string values directly via
the CLI, they will be converted into strings. However, you can preserve
non-string values by writing the key/value pairs to Vault from a JSON file or
using the HTTP API.
This secrets engine honors the distinction between the create and update
capabilities inside ACL policies. The patch capability is also supported
which is used to represent partial updates whereas the update capability
represents full overwrites.
Most secrets engines must be configured in advance before they can perform their
functions. These steps are usually completed by an operator or configuration
management tool.
A v2 kv secrets engine can be enabled by:
$vault secrets enable -version=2 kv
$vault secrets enable -version=2 kv
Or, you can pass kv-v2 as the secrets engine type:
$vault secrets enable kv-v2
$vault secrets enable kv-v2
Additionally, when running a dev-mode server, the v2 kv secrets engine is enabled by default at the
path secret/ (for non-dev servers, it is currently v1). It can be disabled, moved, or enabled multiple times at
different paths. Each instance of the KV secrets engine is isolated and unique.
An existing version 1 kv store can be upgraded to a version 2 kv store via the CLI or API, as shown below. This will start an upgrade process to upgrade the existing key/value data to a versioned format. The mount will be inaccessible during this process. This process could take a long time, so plan accordingly.
Once upgraded to version 2, the former paths at which the data was accessible will no longer suffice. You will need to adjust user policies to add access to the version 2 paths as detailed in the ACL Rules section below. Similarly, users/applications will need to update the paths at which they interact with the kv data once it has been upgraded to version 2.
An existing version 1 kv can be upgraded to a version 2 KV store with the CLI command:
$vault kv enable-versioning secret/Success! Tuned the secrets engine at: secret/
$vault kv enable-versioning secret/Success! Tuned the secrets engine at: secret/
The version 2 kv store uses a prefixed API, which is different from the
version 1 API. Before upgrading from a version 1 kv the ACL rules
should be changed. Also different paths in the version 2 API can be ACL'ed
differently.
Writing and reading versions are prefixed with the data/ path. This policy
that worked for the version 1 kv:
The allowed_parameters, denied_parameters, and required_parameters fields are
not supported for policies used with the version 2 kv store. See the Policies Concepts
for a description of these parameters.
After the secrets engine is configured and a user/machine has a Vault token with
the proper permission, it can generate credentials. The kv secrets engine
allows for writing keys with arbitrary values.
The path-like KV-v1 syntax for referencing a secret (secret/foo) can still
be used in KV-v2, but we recommend using the -mount=secret flag syntax to
avoid mistaking it for the actual path to the secret (secret/data/foo is the
real path).
$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:20:22.985303Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 1====== Data ======Key Value--- -----foo abar b
$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:20:22.985303Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 1====== Data ======Key Value--- -----foo abar b
Write another version, the previous version will still be accessible. The
-cas flag can optionally be passed to perform a check-and-set operation. If
not set the write will be allowed. If set to -cas=0 a write will only be allowed
if the key doesn't exist. If the index is non-zero the write will only be
allowed if the key’s current version matches the version specified in the
cas parameter.
Reading now will return the newest version of the data:
$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:22:23.369372Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----foo aabar bb
$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:22:23.369372Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----foo aabar bb
Partial updates can be accomplished using the vault kv patch command. A
command will initially attempt an HTTP PATCH request which requires the
patch ACL capability. The PATCH request will fail if the token used
is associated with a policy that does not contain the patch capability. In
this case the command will perform a read, local update, and subsequent write
which require both the read and update ACL capabilities.
The -cas flag can optionally be passed to perform a check-and-set operation.
It will only be used in the case of the initial PATCH request. The
read-then-write flow will use the version value from the secret returned by
the read to perform a check-and-set operation in the subsequent write.
The vault kv patch command also supports a -method flag which can be
used to specify HTTP PATCH or read-then-write. The supported values are
patch and rw for HTTP PATCH and read-then-write, respectively.
When deleting data the standard vault kv delete command will perform a
soft delete. It will mark the version as deleted and populate a deletion_time
timestamp. Soft deletes do not remove the underlying version data from storage,
which allows the version to be undeleted. The vault kv undelete command
handles undeleting versions.
A version's data is permanently deleted only when the key has more versions than
are allowed by the max-versions setting, or when using vault kv destroy. When
the destroy command is used the underlying version data will be removed and the
key metadata will be marked as destroyed. If a version is cleaned up by going
over max-versions the version metadata will also be removed from the key.
See the commands below for more information:
The latest version of a key can be deleted with the delete command, this also
takes a -versions flag to delete prior versions:
$vault kv delete -mount=secret my-secretSuccess! Data deleted (if it existed) at: secret/data/my-secret
$vault kv delete -mount=secret my-secretSuccess! Data deleted (if it existed) at: secret/data/my-secret
Versions can be undeleted:
$vault kv undelete -mount=secret -versions=2 my-secretSuccess! Data written to: secret/undelete/my-secret$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:23:21.834403Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----my-value short-lived-s3cr3t
$vault kv undelete -mount=secret -versions=2 my-secretSuccess! Data written to: secret/undelete/my-secret$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:23:21.834403Zcustom_metadata <nil>deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----my-value short-lived-s3cr3t
Destroying a version permanently deletes the underlying data:
$vault kv destroy -mount=secret -versions=2 my-secretSuccess! Data written to: secret/destroy/my-secret
$vault kv destroy -mount=secret -versions=2 my-secretSuccess! Data written to: secret/destroy/my-secret
All versions and key metadata can be tracked with the metadata command & API.
Deleting the metadata key will cause all metadata and versions for that key to
be permanently removed.
See the commands below for more information:
All metadata and versions for a key can be viewed:
A secret's key metadata can contain custom metadata used to describe the secret.
The data will be stored as string-to-string key-value pairs.
The -custom-metadata flag can be repeated to add multiple key-value pairs.
The vault kv metadata put command can be used to fully overwrite the value of custom_metadata:
$vault kv metadata put -mount=secret -custom-metadata=foo=abc -custom-metadata=bar=123 my-secretSuccess! Data written to: secret/metadata/my-secret$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:22:23.369372Zcustom_metadata map[bar:123 foo:abc]deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----foo aabar bb
$vault kv metadata put -mount=secret -custom-metadata=foo=abc -custom-metadata=bar=123 my-secretSuccess! Data written to: secret/metadata/my-secret$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:22:23.369372Zcustom_metadata map[bar:123 foo:abc]deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----foo aabar bb
The vault kv metadata patch command can be used to partially overwrite the value of custom_metadata.
The following invocation will update custom_metadata sub-field foo but leave bar untouched:
$vault kv metadata patch -mount=secret -custom-metadata=foo=def my-secretSuccess! Data written to: secret/metadata/my-secret$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:22:23.369372Zcustom_metadata map[bar:123 foo:def]deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----foo aabar bb
$vault kv metadata patch -mount=secret -custom-metadata=foo=def my-secretSuccess! Data written to: secret/metadata/my-secret$vault kv get -mount=secret my-secret====== Metadata ======Key Value--- -----created_time 2019-06-19T17:22:23.369372Zcustom_metadata map[bar:123 foo:def]deletion_time n/adestroyed falseversion 2====== Data ======Key Value--- -----foo aabar bb
Permanently delete all metadata and versions for a key:
$vault kv metadata delete -mount=secret my-secretSuccess! Data deleted (if it existed) at: secret/metadata/my-secret
$vault kv metadata delete -mount=secret my-secretSuccess! Data deleted (if it existed) at: secret/metadata/my-secret