Key / Value —— Version 2

kv 机密引擎用于在 Vault 使用的物理存储中存储任意机密。

键名必须始终是字符串。如果您直接通过命令行编写非字符串类型的值,它们将被转换为字符串。但是,您可以通过从 JSON 文件或使用 HTTP API 写入键值数据来保留非字符串类型的值。

这个机密引擎能够区分 ACL 策略内的 createupdate 功能之间的区别。还支持 patch 功能,用于表示部分更新,而 update 功能表示完全覆盖。

配置

大部分机密引擎在工作之前必须要先进行配置。这些步骤通常是由系统管理员来完成。

用以下命令启用一个 v2 版本的 kv 机密引擎:

$ vault secrets enable -version=2 kv

或者可以用 kv-v2 作为机密引擎类型:

$ vault secrets enable kv-v2

此外,在运行"dev"模式的测试服务器时,默认会在路径 secret/ 处启用 v2 kv 机密引擎(对于非"dev"服务器,当前为 v1)。可以在多个不同的路径禁用、移动或启用它。 kv 机密引擎在每个挂载点上启用的实例都是隔离且唯一的。

从 Version 1 升级到 Version 2

现有的 Version 1 kv 存储可以通过命令行或 API 升级到 Version 2 kv 存储。这将启动升级过程,将现有的键/值数据升级为版本化的格式。在此过程中将无法访问相关路径。此过程可能需要很长时间,因此提前做好计划。

升级到 Version 2 后,以前用来访问数据的路径将不再适用。您将需要调整用户策略以添加对 Version 2 路径的访问,如下面的 ACL 规则部分所述。同样,一旦升级到 Version 2,用户/应用程序将需要更新他们与 kv 数据交互的路径。

可以使用下面的命令将 Version 1 升级到 Version 2:

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

或者调用 API:

$ cat payload.json
{
  "options": {
      "version": "2"
  }
}

$ curl \
    --header "X-Vault-Token: ..." \
    --request POST \
    --data @payload.json \
    http://127.0.0.1:8200/v1/sys/mounts/secret/tune

ACL 规则

Version 2 kv 存储使用带前缀的 API,这与 Version 1 API 不同。在从 Version 1 kv 升级之前,要更改 ACL 规则。Version 2 API 中的不同路径也可以采用不同的 ACL。

读写 Version 2 数据都要以 data/ 为前缀。以下策略适用于版本 1 kv

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

到 Version 2 就应该写成:

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

数据删除的权限路径也不一样,要让策略授予删除键的最新版本的权限:

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"]
}

不能为 Version 2 的 kv 存储设置包含 allowed_pa​​rametersdenied_pa​​rametersrequired_pa​​rameters 字段的策略。

可用标志

配置完机密引擎后拥有合适权限的 Vault 令牌的用户或者机器就可以用它来读写数据了。kv 机密引擎允许在键值对的值中写入任意数据。

读写任意数据

  1. 写入数据
$ vault kv put secret/my-secret foo=a bar=b
Key              Value
---              -----
created_time     2019-06-19T17:20:22.985303Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          1
  1. 读取数据:
$ vault kv get secret/my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2019-06-19T17:20:22.985303Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          1

====== Data ======
Key         Value
---         -----
foo         a
  1. 再次向同一键写入新版本的数据,之前的版本还是可以访问的。可以选择传递 -cas 标志来执行 check-and-set 操作。如果设置为 -cas=0,则仅当密钥不存在时才允许写入。如果 -cas 不为零,则仅当密钥的当前版本与 cas 参数中指定的版本一致时才允许写入。
$ vault kv put -cas=1 secret/my-secret foo=aa bar=bb
Key              Value
---              -----
created_time     2019-06-19T17:22:23.369372Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          2
  1. 再读一次就可以得到最新版本的数据:
$ vault kv get secret/my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2019-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

可以使用 vault kv patch 命令实现部分更新。命令将首先尝试发送一个需要 patch ACL 权限的 HTTP PATCH 请求。如果使用的令牌关联的策略中不包含 patch 权限,那么 PATCH 请求将失败。在这种情况下,该命令将读取最新数据,在本地更新后写回,这一系列操作需要在 ACL 中拥有 readupdate 权限。

可以选择使用 -cas 参数来执行 check-and-set 操作。它只会在一开始的 PATCH 请求中使用。 读取后完整更新的流程将使用读取返回的机密中的 version 值来在后续写入中执行 check-and-set 操作。

$ vault kv patch -cas=2 secret/my-secret bar=bbb
Key              Value
---              -----
created_time     2019-06-19T17:23:49.199802Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          3
  1. vault kv patch 命令还支持 -method 标志,可用于指定是使用 HTTP PATCH 还是先读后写。支持的值分别是 patchrw

使用 patch 方法执行部分更新:

$ vault kv patch -method=patch -cas=2 secret/my-secret bar=bbb
Key              Value
---              -----
created_time     2019-06-19T17:23:49.199802Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          3

使用 rw 方法进行更新:

$ vault kv patch -method=rw secret/my-secret bar=bbb
Key              Value
---              -----
created_time     2019-06-19T17:23:49.199802Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          3
  1. 部分更新后读取机密会可以从返回的最新版本的数据中看到,只有部分字段发生了变更:
$ vault kv get secret/my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2019-06-19T17:23:49.199802Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          3

====== Data ======
Key         Value
---         -----
foo         aa
bar         bbb
  1. 可以使用 -version 标志查看先前的版本:
$ vault kv get -version=1 secret/my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2019-06-19T17:20:22.985303Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          1

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

删除 / 彻底删除(Destroy)数据

删除数据时,普通的 vault kv delete 命令将执行软删除。它将将该版本标记为已删除并填充一个 deletion_time 时间戳。软删除不会从存储中删除底层版本数据,这使我们可以撤销删除版本。 vault kv undelete 命令可以撤销删除版本。

仅当键的版本数超过 max-versions 设置允许的数量时,或使用 vault kv destroy 命令时,才会永久删除版本数据。当使用 destroy 命令时,底层版本数据将被删除,并且键值对的元数据将被标记为已销毁。如果一个版本是通过 max-versions 机制被清理的,那么它的版本元数据也将从键值对中删除。

以下操作可以提供进一步的说明:

  1. 可以使用 delete 命令删除键值对的最新版本,也可以通过 -versions 标志来删除过去的版本:
$ vault kv delete secret/my-secret
  1. 可以撤销删除的版本:
$ vault kv undelete -versions=2 secret/my-secret
Success! Data written to: secret/undelete/my-secret

$ vault kv get secret/my-secret
====== Metadata ======
Key              Value
---              -----
created_time     2019-06-19T17:23:21.834403Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    n/a
destroyed        false
version          2

====== Data ======
Key         Value
---         -----
my-value    short-lived-s3cr3t
  1. 彻底删除一个版本的数据:
$ vault kv destroy -versions=2 secret/my-secret
Success! Data written to: secret/destroy/my-secret

键的元数据

可以使用元数据命令和 API 跟踪键的所有版本和元数据。删除键的元数据将导致该键值对的所有元数据和版本被永久删除。

  1. 查询一个键的所有元数据和版本:
$ vault kv metadata get secret/my-secret
========== Metadata ==========
Key                     Value
---                     -----
cas_required            false
created_time            2019-06-19T17:20:22.985303Z
current_version         2
custom_metadata         map[bar:123 foo:abc]
delete_version_after    0s
max_versions            0
oldest_version          0
updated_time            2019-06-19T17:22:23.369372Z

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

====== Version 2 ======
Key              Value
---              -----
created_time     2019-06-19T17:22:23.369372Z
deletion_time    n/a
destroyed        true
  1. 可以设置一个键的元数据配置:
$ vault kv metadata put -max-versions 2 -delete-version-after="3h25m19s" secret/my-secret
Success! Data written to: secret/metadata/my-secret

-delete-version-after 设置只对新版本数据有效。下次写入的数据就会应用 -max-versions 的约束:

$ vault kv put secret/my-secret my-value=newer-s3cr3t
Key              Value
---              -----
created_time     2019-06-19T17:31:16.662563Z
custom_metadata  map[bar:123 foo:abc]
deletion_time    2019-06-19T20:56:35.662563Z
destroyed        false
version          4

当一个键的版本超过 -max-versions 设置的限制,旧版本会被清理:

$ vault kv metadata get secret/my-secret
========== Metadata ==========
Key                     Value
---                     -----
cas_required            false
created_time            2019-06-19T17:20:22.985303Z
current_version         4
custom_metadata         map[bar:123 foo:abc]
delete_version_after    3h25m19s
max_versions            2
oldest_version          3
updated_time            2019-06-19T17:31:16.662563Z

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

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

机密键值对的元数据可以包含用于描述机密的自定义元数据。数据将存储为字符串到字符串的键值对。如果设置了 -custom-metadata 标志,则 custom_metadata 的值将被覆盖。 可以重复使用 -custom-metadata 标志添加多个键值对:

$ vault kv metadata put -custom-metadata=foo=abc -custom-metadata=bar=123 secret/my-secret
  1. 永久删除一个键的所有元数据和版本:
$ vault kv metadata delete secret/my-secret
Success! Data deleted (if it existed) at: secret/metadata/my-secret

results matching ""

    No results matching ""