1
0

KV: Update 'versioned' naming to 'v2' (#4293)

* Update 'versioned' naming to 'v2'

* Make sure options are set

* Fix description of auth flag

* Review feedback
This commit is contained in:
Brian Kassouf 2018-04-09 09:39:32 -07:00 committed by GitHub
parent 279810a6a6
commit 915e452c0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 148 additions and 115 deletions

View File

@ -3,6 +3,7 @@ package command
import (
"flag"
"fmt"
"strconv"
"strings"
"time"
@ -29,6 +30,7 @@ type AuthEnableCommand struct {
flagOptions map[string]string
flagLocal bool
flagSealWrap bool
flagVersion int
}
func (c *AuthEnableCommand) Synopsis() string {
@ -160,6 +162,13 @@ func (c *AuthEnableCommand) Flags() *FlagSets {
Usage: "Enable seal wrapping of critical values in the secrets engine.",
})
f.IntVar(&IntVar{
Name: "version",
Target: &c.flagVersion,
Default: 0,
Usage: "Select the version of the auth method to run. Not supported by all auth methods.",
})
return set
}
@ -211,6 +220,13 @@ func (c *AuthEnableCommand) Run(args []string) int {
// Append a trailing slash to indicate it's a path in output
authPath = ensureTrailingSlash(authPath)
if c.flagVersion > 0 {
if c.flagOptions == nil {
c.flagOptions = make(map[string]string)
}
c.flagOptions["version"] = strconv.Itoa(c.flagVersion)
}
authOpts := &api.EnableAuthOptions{
Type: authType,
Description: c.flagDescription,

View File

@ -77,7 +77,7 @@ func (c *KVEnableVersioningCommand) Run(args []string) int {
if err := client.Sys().TuneMount(mountPath, api.MountConfigInput{
Options: map[string]string{
"versioned": "true",
"version": "2",
},
}); err != nil {
c.UI.Error(fmt.Sprintf("Error tuning secrets engine %s: %s", mountPath, err))

View File

@ -18,7 +18,7 @@ func kvReadRequest(client *api.Client, path string, params map[string]string) (*
if r.Headers == nil {
r.Headers = http.Header{}
}
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
for k, v := range params {
r.Params.Set(k, v)
@ -53,7 +53,7 @@ func kvListRequest(client *api.Client, path string) (*api.Secret, error) {
if r.Headers == nil {
r.Headers = http.Header{}
}
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
// Set this for broader compatibility, but we use LIST above to be able to
// handle the wrapping lookup function
@ -89,7 +89,7 @@ func kvWriteRequest(client *api.Client, path string, data map[string]interface{}
if r.Headers == nil {
r.Headers = http.Header{}
}
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
if err := r.SetJSONBody(data); err != nil {
return nil, err
}
@ -127,7 +127,7 @@ func kvDeleteRequest(client *api.Client, path string) (*api.Secret, error) {
if r.Headers == nil {
r.Headers = http.Header{}
}
r.Headers.Add(consts.VaultKVCLIClientHeader, "v1")
r.Headers.Add(consts.VaultKVCLIClientHeader, "v2")
resp, err := client.RawRequest(r)
if resp != nil {
defer resp.Body.Close()

View File

@ -3,6 +3,7 @@ package command
import (
"flag"
"fmt"
"strconv"
"strings"
"time"
@ -30,6 +31,7 @@ type SecretsEnableCommand struct {
flagOptions map[string]string
flagLocal bool
flagSealWrap bool
flagVersion int
}
func (c *SecretsEnableCommand) Synopsis() string {
@ -177,6 +179,13 @@ func (c *SecretsEnableCommand) Flags() *FlagSets {
Usage: "Enable seal wrapping of critical values in the secrets engine.",
})
f.IntVar(&IntVar{
Name: "version",
Target: &c.flagVersion,
Default: 0,
Usage: "Select the version of the engine to run. Not supported by all engines.",
})
return set
}
@ -226,6 +235,13 @@ func (c *SecretsEnableCommand) Run(args []string) int {
}
}
if c.flagVersion > 0 {
if c.flagOptions == nil {
c.flagOptions = make(map[string]string)
}
c.flagOptions["version"] = strconv.Itoa(c.flagVersion)
}
// Append a trailing slash to indicate it's a path in output
mountPath = ensureTrailingSlash(mountPath)

View File

@ -168,7 +168,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -221,7 +221,7 @@ func TestSysMounts_headerAuth(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",

View File

@ -37,7 +37,7 @@ func TestSysMounts(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -90,7 +90,7 @@ func TestSysMounts(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -158,7 +158,7 @@ func TestSysMount(t *testing.T) {
"type": "kv",
"description": "foo",
"options": map[string]string{
"versioned": "true",
"version": "2",
},
})
testResponseStatus(t, resp, 204)
@ -185,7 +185,7 @@ func TestSysMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"secret/": map[string]interface{}{
"description": "key/value secret storage",
@ -198,7 +198,7 @@ func TestSysMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -251,7 +251,7 @@ func TestSysMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"secret/": map[string]interface{}{
"description": "key/value secret storage",
@ -264,7 +264,7 @@ func TestSysMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -391,7 +391,7 @@ func TestSysRemount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -457,7 +457,7 @@ func TestSysRemount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -552,7 +552,7 @@ func TestSysUnmount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -605,7 +605,7 @@ func TestSysUnmount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -793,7 +793,7 @@ func TestSysTuneMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -859,7 +859,7 @@ func TestSysTuneMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -955,7 +955,7 @@ func TestSysTuneMount(t *testing.T) {
// mark as versioned
resp = testHttpPost(t, token, addr+"/v1/sys/mounts/foo/tune", map[string]interface{}{
"options": map[string]string{
"versioned": "true",
"version": "2",
},
})
testResponseStatus(t, resp, 200)
@ -980,7 +980,7 @@ func TestSysTuneMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"secret/": map[string]interface{}{
"description": "key/value secret storage",
@ -993,7 +993,7 @@ func TestSysTuneMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -1046,7 +1046,7 @@ func TestSysTuneMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"secret/": map[string]interface{}{
"description": "key/value secret storage",
@ -1059,7 +1059,7 @@ func TestSysTuneMount(t *testing.T) {
},
"local": false,
"seal_wrap": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"sys/": map[string]interface{}{
"description": "system endpoints used for control, policy and debugging",
@ -1131,12 +1131,12 @@ func TestSysTuneMount(t *testing.T) {
"default_lease_ttl": json.Number("259196400"),
"max_lease_ttl": json.Number("259200000"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("259196400"),
"max_lease_ttl": json.Number("259200000"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseStatus(t, resp, 200)
@ -1166,12 +1166,12 @@ func TestSysTuneMount(t *testing.T) {
"default_lease_ttl": json.Number("40"),
"max_lease_ttl": json.Number("80"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("40"),
"max_lease_ttl": json.Number("80"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseStatus(t, resp, 200)
@ -1263,14 +1263,14 @@ func TestSysTuneMount_nonHMACKeys(t *testing.T) {
"force_no_cache": false,
"audit_non_hmac_request_keys": []interface{}{"foo"},
"audit_non_hmac_response_keys": []interface{}{"bar"},
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"audit_non_hmac_request_keys": []interface{}{"foo"},
"audit_non_hmac_response_keys": []interface{}{"bar"},
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseBody(t, resp, &actual)
expected["request_id"] = actual["request_id"]
@ -1305,12 +1305,12 @@ func TestSysTuneMount_nonHMACKeys(t *testing.T) {
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseBody(t, resp, &actual)
expected["request_id"] = actual["request_id"]
@ -1341,12 +1341,12 @@ func TestSysTuneMount_listingVisibility(t *testing.T) {
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseBody(t, resp, &actual)
expected["request_id"] = actual["request_id"]
@ -1377,13 +1377,13 @@ func TestSysTuneMount_listingVisibility(t *testing.T) {
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"listing_visibility": "unauth",
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"listing_visibility": "unauth",
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseBody(t, resp, &actual)
expected["request_id"] = actual["request_id"]
@ -1419,13 +1419,13 @@ func TestSysTuneMount_passthroughRequestHeaders(t *testing.T) {
"data": map[string]interface{}{
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
"force_no_cache": false,
"passthrough_request_headers": []interface{}{"X-Vault-Foo"},
},
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
"force_no_cache": false,
"passthrough_request_headers": []interface{}{"X-Vault-Foo"},
}
@ -1457,12 +1457,12 @@ func TestSysTuneMount_passthroughRequestHeaders(t *testing.T) {
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
},
"default_lease_ttl": json.Number("2764800"),
"max_lease_ttl": json.Number("2764800"),
"force_no_cache": false,
"options": map[string]interface{}{"versioned": "true"},
"options": map[string]interface{}{"version": "2"},
}
testResponseBody(t, resp, &actual)
expected["request_id"] = actual["request_id"]

View File

@ -1643,6 +1643,22 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d
"plugin_name must be provided for plugin backend"),
logical.ErrInvalidRequest
}
case "kv-v1":
// Alias KV v1
logicalType = "kv"
if options == nil {
options = map[string]string{}
}
options["version"] = "1"
case "kv-v2":
// Alias KV v2
logicalType = "kv"
if options == nil {
options = map[string]string{}
}
options["version"] = "2"
}
// Copy over the force no cache if set
@ -1665,15 +1681,6 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d
config.PassthroughRequestHeaders = apiConfig.PassthroughRequestHeaders
}
// Alias versioned KV
if logicalType == "vkv" {
logicalType = "kv"
if options == nil {
options = map[string]string{}
}
options["versioned"] = "true"
}
// Create the mount entry
me := &MountEntry{
Table: mountTableType,
@ -2099,16 +2106,16 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
b.Core.logger.Info("core: mount tuning of options", "path", path, "options", options)
// Special case to make sure we can not disable versioning once it's
// enabeled. If the vkv backend suports downgrading this can be removed.
meVersioned, err := parseutil.ParseBool(mountEntry.Options["versioned"])
meVersion, err := parseutil.ParseInt(mountEntry.Options["version"])
if err != nil {
return nil, errwrap.Wrapf("unable to parse mount entry: {{err}}", err)
}
optVersioned, err := parseutil.ParseBool(options["versioned"])
optVersion, err := parseutil.ParseInt(options["version"])
if err != nil {
return handleError(errwrap.Wrapf("unable to parse options: {{err}}", err))
}
if meVersioned && !optVersioned {
return logical.ErrorResponse("cannot disable versioning once it's enabled"), logical.ErrInvalidRequest
if meVersion > optVersion {
return logical.ErrorResponse(fmt.Sprintf("cannot downgrade mount from version %d", meVersion)), logical.ErrInvalidRequest
}
oldVal := mountEntry.Options
@ -2125,15 +2132,9 @@ func (b *SystemBackend) handleTuneWriteCommon(ctx context.Context, path string,
return handleError(err)
}
// Another special case to add a warning if we are going to be
// upgrading.
oldVersioned, err := parseutil.ParseBool(oldVal["versioned"])
if err != nil {
return nil, errwrap.Wrapf("unable to parse mount entry: {{err}}", err)
}
if !oldVersioned && optVersioned {
if meVersion < optVersion {
resp = &logical.Response{}
resp.AddWarning("Uprading from non-versioned to versioned data. This backend will be unavailable for a brief period and will resume service shortly.")
resp.AddWarning(fmt.Sprintf("Upgrading mount from version %d to version %d. This mount will be unavailable for a brief period and will resume service shortly.", meVersion, optVersion))
}
// Reload the backend to kick off the upgrade process.

View File

@ -132,7 +132,7 @@ func TestSystemBackend_mounts(t *testing.T) {
"local": false,
"seal_wrap": false,
"options": map[string]string{
"versioned": "true",
"version": "2",
},
},
"sys/": map[string]interface{}{
@ -195,7 +195,7 @@ func TestSystemBackend_mount(t *testing.T) {
req.Data["local"] = true
req.Data["seal_wrap"] = true
req.Data["options"] = map[string]string{
"versioned": "true",
"version": "2",
}
resp, err := b.HandleRequest(context.Background(), req)
@ -228,7 +228,7 @@ func TestSystemBackend_mount(t *testing.T) {
"local": false,
"seal_wrap": false,
"options": map[string]string{
"versioned": "true",
"version": "2",
},
},
"sys/": map[string]interface{}{
@ -286,7 +286,7 @@ func TestSystemBackend_mount(t *testing.T) {
"local": true,
"seal_wrap": true,
"options": map[string]string{
"versioned": "true",
"version": "2",
},
},
}

View File

@ -959,7 +959,7 @@ func (c *Core) defaultMountTable() *MountTable {
Accessor: mountAccessor,
BackendAwareUUID: bUUID,
Options: map[string]string{
"versioned": "true",
"version": "2",
},
}
table.Entries = append(table.Entries, kvMount)

View File

@ -8,10 +8,10 @@ description: |-
# KV Secrets Engine (API)
This backend can be run in one of two modes. Each of which have a distinct API.
Choose the mode below you are running. For more information on the two modes see
the [Vault kv documentation](/docs/secrets/kv/index.html).
This backend can be run in one of two versions. Each of which have a distinct API.
Choose the version below you are running. For more information on the KV secrets
engine see the [Vault kv documentation](/docs/secrets/kv/index.html).
- [Normal KV API](/api/secret/kv/kv.html)
- [KV Version 1 API](/api/secret/kv/kv-v1.html)
- [Versioned KV API](/api/secret/kv/versioned-kv.html)
- [KV Version 2 API](/api/secret/kv/kv-v2.html)

View File

@ -1,12 +1,12 @@
---
layout: "api"
page_title: "KV - Secrets Engines - HTTP API"
sidebar_current: "docs-http-secret-kv-nonversioned"
sidebar_current: "docs-http-secret-kv-v1"
description: |-
This is the API documentation for the Vault KV secrets engine.
---
# KV Secrets Engine (API)
# KV Secrets Engine - Version 1 (API)
This is the API documentation for the Vault KV secrets engine. For general
information about the usage and operation of the kv secrets engine, please

View File

@ -1,12 +1,12 @@
---
layout: "api"
page_title: "KV - Secrets Engines - HTTP API"
sidebar_current: "docs-http-secret-kv-versioned"
sidebar_current: "docs-http-secret-kv-v2"
description: |-
This is the API documentation for the Vault KV secrets engine.
---
# Versioned KV Secrets Engine (API)
# KV Secrets Engine - Version 2 (API)
This is the API documentation for the Vault KV secrets engine while running in
versioned mode. For general information about the usage and operation of the kv
@ -19,7 +19,7 @@ possible to enable secrets engines at any location, please update your API calls
accordingly.
## Configure the Versioned K/V Backend
## Configure the KV Engine
This path configures backend level settings that are applied to every key in the
key-value store.

View File

@ -14,7 +14,7 @@ modes. It can be a generic Key-Value store that stores one value for a key.
Versioning can be enabled and a configurable number of versions for each key
will be stored.
## Non-Versioned Mode
## KV Version 1
When running the `kv` secrets backend non-versioned only the most recently
written value for a key will be preserved. The benefits of non-versioned `kv`
@ -23,15 +23,15 @@ is stored. Additionally, requests going to a backend configured this way will be
more performant because for any given request there will be fewer storage calls
and no locking.
More information about running in this mode can be found in the [K/V
Docs](/docs/secrets/kv/kv.html)
More information about running in this mode can be found in the [K/V Version 1
Docs](/docs/secrets/kv/kv-v1.html)
## Versioned Mode
## KV Version 2
When running the `kv` backend in versioned mode a key can retain a configurable
number of versions. This defaults to 10 versions. The older versions' metadata
and data can be retrieved. Additionally, Check-and-Set operations can be used to
avoid overwritting data unintentionally.
When running v2 of the `kv` backend a key can retain a configurable number of
versions. This defaults to 10 versions. The older versions' metadata and data
can be retrieved. Additionally, Check-and-Set operations can be used to avoid
overwritting data unintentionally.
When a version is deleted the underlying data is not removed, rather it is
marked as deleted. Deleted versions can be undeleted. To permanently remove a
@ -40,5 +40,5 @@ versions and metadata for a key can be deleted by deleting on the metadata
command or API endpoint. Each of these operations can be ACL'ed differently,
restricting who has permissions to soft delete, undelete, or fully remove data.
More information about running in this mode can be found in the [Versioned K/V
Docs](/docs/secrets/kv/versioned-kv.html)
More information about running in this mode can be found in the [K/V Version 2
Docs](/docs/secrets/kv/kv-v2.html)

View File

@ -1,12 +1,12 @@
---
layout: "docs"
page_title: "KV - Secrets Engines"
sidebar_current: "docs-secrets-kv-nonversioned"
sidebar_current: "docs-secrets-kv-v1"
description: |-
The KV secrets engine can store arbitrary secrets.
---
# KV Secrets Engine
# KV Secrets Engine - Version 1
The `kv` secrets engine is used to store arbitrary secrets within the
configured physical storage for Vault.
@ -28,10 +28,10 @@ secret's path.
## Setup
To enable a non-versioned kv store:
To enable a version 1 kv store:
```
vault secrets enable kv
vault secrets enable -version=1 kv
```
## Usage
@ -106,5 +106,5 @@ ttl 30m
## API
The KV secrets engine has a full HTTP API. Please see the
[KV secrets engine API](/api/secret/kv/kv.html) for more
[KV secrets engine API](/api/secret/kv/kv-v1.html) for more
details.

View File

@ -1,12 +1,12 @@
---
layout: "docs"
page_title: "KV - Secrets Engines"
sidebar_current: "docs-secrets-kv-versioned"
sidebar_current: "docs-secrets-kv-v2"
description: |-
The KV secrets engine can store arbitrary secrets.
---
# Versioned KV Secrets Engine
# KV Secrets Engine - Version 2
The `kv` secrets engine is used to store arbitrary secrets within the
configured physical storage for Vault.
@ -25,20 +25,20 @@ 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 versioned `kv` secrets engine can be enabled by:
A v2 `kv` secrets engine can be enabled by:
```
$ vault secrets enable vkv
$ vault secrets enable -version=2 kv
```
Additionally, the versioned `kv` secrets engine is enabled by default at the
Additionally, the v2 `kv` secrets engine is enabled by default at the
path `secret/`. It can be disabled, moved, or enabled multiple times at
different paths. Each instance of the KV secrets engine is isolated and unique.
## Upgrading from Non-Versioned
## Upgrading from Version 1
An existing non-versioned kv can be easily upgraded to a versioned key/value
store with the CLI command:
An existing version 1 kv can be easily upgraded to a version 2 KV store with the
CLI command:
```
$ vault kv enable-versioning secret/
@ -51,7 +51,7 @@ or via the API:
$ cat payload.json
{
"options": {
"versioned": "true"
"version": "2"
}
}
@ -68,13 +68,13 @@ process could take a long time, so plan accordingly.
## ACL Rules
The versioned kv store uses a prefixed API, which is different from the
non-versioned store. Before upgrading from a non-versioned kv the ACL rules
should be changed. Also different paths in the versioned API can be ACL'ed
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 non-versioned kv:
that worked for the version 1 kv:
```
path "secret/dev/team-1/*" {
@ -146,7 +146,7 @@ path "secret/metadata/dev/team-1/*" {
}
```
See the [API Specification](/api/secret/kv/versioned-kv.html) for more
See the [API Specification](/api/secret/kv/kv-v2.html) for more
information.
## Usage
@ -381,5 +381,5 @@ See the commands below for more information:
## API
The KV secrets engine has a full HTTP API. Please see the
[KV secrets engine API](/api/secret/kv/versioned-kv.html) for more
[KV secrets engine API](/api/secret/kv/kv-v2.html) for more
details.

View File

@ -59,11 +59,11 @@
<li<%= sidebar_current("docs-http-secret-kv") %>>
<a href="/api/secret/kv/index.html">Key/Value</a>
<ul class="nav">
<li<%= sidebar_current("docs-http-secret-kv-nonversioned") %>>
<a href="/api/secret/kv/kv.html">K/V</a>
<li<%= sidebar_current("docs-http-secret-kv-v1") %>>
<a href="/api/secret/kv/kv-v1.html">K/V Version 1</a>
</li>
<li<%= sidebar_current("docs-http-secret-kv-versioned") %>>
<a href="/api/secret/kv/versioned-kv.html">Versioned K/V</a>
<li<%= sidebar_current("docs-http-secret-kv-v2") %>>
<a href="/api/secret/kv/kv-v2.html">K/V Version 2</a>
</li>
</ul>
</li>

View File

@ -397,11 +397,11 @@
<li<%= sidebar_current("docs-secrets-kv") %>>
<a href="/docs/secrets/kv/index.html">Key/Value</a>
<ul class="nav">
<li<%= sidebar_current("docs-secrets-kv-nonversioned") %>>
<a href="/docs/secrets/kv/kv.html">K/V</a>
<li<%= sidebar_current("docs-secrets-kv-v1") %>>
<a href="/docs/secrets/kv/kv-v1.html">K/V Version 1</a>
</li>
<li<%= sidebar_current("docs-secrets-kv-versioned") %>>
<a href="/docs/secrets/kv/versioned-kv.html">Versioned K/V</a>
<li<%= sidebar_current("docs-secrets-kv-v2") %>>
<a href="/docs/secrets/kv/kv-v2.html">K/V Version 2</a>
</li>
</ul>
</li>