Key / Value —— Version 2
kv
机密引擎用于在 Vault 使用的物理存储中存储任意机密。
键名必须始终是字符串。如果您直接通过命令行编写非字符串类型的值,它们将被转换为字符串。但是,您可以通过从 JSON 文件或使用 HTTP API 写入键值数据来保留非字符串类型的值。
这个机密引擎能够区分 ACL 策略内的 create
和 update
功能之间的区别。还支持 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_parameters
、 denied_parameters
和 required_parameters
字段的策略。
可用标志
配置完机密引擎后拥有合适权限的 Vault 令牌的用户或者机器就可以用它来读写数据了。kv
机密引擎允许在键值对的值中写入任意数据。
读写任意数据
- 写入数据
$ 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
- 读取数据:
$ 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
- 再次向同一键写入新版本的数据,之前的版本还是可以访问的。可以选择传递 -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
- 再读一次就可以得到最新版本的数据:
$ 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 中拥有 read
和 update
权限。
可以选择使用 -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
vault kv patch
命令还支持-method
标志,可用于指定是使用 HTTPPATCH
还是先读后写。支持的值分别是patch
和rw
。
使用 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
- 部分更新后读取机密会可以从返回的最新版本的数据中看到,只有部分字段发生了变更:
$ 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
- 可以使用
-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
机制被清理的,那么它的版本元数据也将从键值对中删除。
以下操作可以提供进一步的说明:
- 可以使用
delete
命令删除键值对的最新版本,也可以通过-versions
标志来删除过去的版本:
$ vault kv delete secret/my-secret
- 可以撤销删除的版本:
$ 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
- 彻底删除一个版本的数据:
$ vault kv destroy -versions=2 secret/my-secret
Success! Data written to: secret/destroy/my-secret
键的元数据
可以使用元数据命令和 API 跟踪键的所有版本和元数据。删除键的元数据将导致该键值对的所有元数据和版本被永久删除。
- 查询一个键的所有元数据和版本:
$ 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
- 可以设置一个键的元数据配置:
$ 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
- 永久删除一个键的所有元数据和版本:
$ vault kv metadata delete secret/my-secret
Success! Data deleted (if it existed) at: secret/metadata/my-secret