KV Secrets Engine v2 是 Vault 最常用的秘密引擎,用于安全存储和版本化管理静态敏感数据,如数据库凭证、API 密钥与配置信息。

与专注于“加密即服务”的 Transit 引擎不同,KV v2 的核心是凭据的存储、版本控制与生命周期管理

一、核心概念与工作流程

KV v2 核心概念

概念说明
挂载路径 (Mount Path)KV v2 引擎在 Vault 中的挂载点,例如 /secret。所有秘密都存储在此路径之下。
数据路径 (Data Path)存储具体秘密数据的完整路径,格式为:/data/。这是执行put、get操作的对象。
元数据路径 (Metadata Path)存储秘密元信息的路径,格式为:/metadata/。用于管理版本策略和查看元数据。
秘密版本每次写入(创建或更新)秘密都会生成一个新版本号,从 1 开始递增。历史版本默认保留。
秘密元数据每个秘密都关联的元信息,包含创建时间、所有版本号、删除状态以及自定义的版本保留策略。

KV v2 完整工作流程

​ 1. 启用引擎:在特定路径(如 /secret)启用 KV v2 引擎。

​ 2. 写入秘密:通过数据路径写入键值对,创建初始版本。

​ 3. 读取秘密:从数据路径读取最新或指定版本的秘密。

​ 4. 更新与管理:通过全量更新(put)、局部更新(patch)、删除(delete)或销毁(destroy)来管理秘密。

​ 5. 配置策略:通过元数据路径配置版本的自动保留与删除策略。

二、启用 KV v2 引擎

KV v2 引擎可以挂载在默认路径或自定义路径下

操作命令说明
在默认路径启用vault secrets enable kv-v2通常挂载到 /secret 路径。
在自定义路径启用vault secrets enable -path=app-secrets kv-v2挂载到自定义路径 /app-secrets。

示例输出

1
2
> vault secrets enable kv-v2
Success! Enabled the kv-v2 secrets engine at: secret/
1
vault secrets enable -path=cipherhub-secrets kv-v2

Clipboard_Screenshot_1766742927

查看所有的挂载点

1
vault secrets list

Clipboard_Screenshot_1766742957

禁用挂载点

1
vault secrets disable test-secrets/

Clipboard_Screenshot_1766742987

三、秘密数据的写入与读取

创建与全量更新 (Put)

vault kv put 命令执行全量写入

如果路径已存在,会创建新版本并完全覆盖旧数据。

1
2
# 创建初始版本 (Version 1)
vault kv put secret/myapp/db username="admin" password="pawd111"

Clipboard_Screenshot_1766743015

1
2
# 全量更新,创建 Version 2 (将完全替换 username 和 password)
vault kv put secret/myapp/db connection_string="host=db;port=5432"

Clipboard_Screenshot_1766743039

读取秘密 (Get)

​ ● 读取****凭据列表

1
vault kv list secret/

Clipboard_Screenshot_1766743064

1
vault kv list secret/myapp/

Clipboard_Screenshot_1766743085

​ ● 读取最新版本(默认行为):

1
vault kv get secret/myapp/db

Clipboard_Screenshot_1766743118

​ ● 读取指定历史版本

1
vault kv get -version=1 secret/myapp/db

Clipboard_Screenshot_1766743145

​ ● 按 JSON 格式读取凭据

1
vault kv get -format=json secret/myapp/db

image-20251226175937313

局部更新 (Patch)

patch 操作只更新指定的字段,不影响其他已存在的字段

1
2
3
# 假设当前版本数据为: {“connection_string”: “host=db;port=5432”}
# 仅添加 `ssl_mode` 字段,创建 Version 3
vault kv patch secret/myapp/db ssl_mode="require" port="5432"

Clipboard_Screenshot_1766743200

Clipboard_Screenshot_1766743212

查看秘密的元数据

1
vault kv metadata get secret/myapp/db

Clipboard_Screenshot_1766743237

四、版本与删除管理

软删除秘密

vault kv delete secret/myapp/db

Clipboard_Screenshot_1766743269

image-20251226180122204

Clipboard_Screenshot_1766743292

恢复已删除版本

1
vault kv undelete -versions=3 secret/myapp/db

Clipboard_Screenshot_1766743321

软删除指定版本

1
vault kv delete -versions=2 secret/myapp/db

Clipboard_Screenshot_1766743342

Clipboard_Screenshot_1766743357

永久销毁版本

1
vault kv destroy -versions=1 secret/myapp/db

Clipboard_Screenshot_1766743382

Clipboard_Screenshot_1766743397

Clipboard_Screenshot_1766743413

删除操作对比

操作类型命令示例效果可恢复性
软删除 (最新版本)vault kv delete secret/myapp/db标记最新版本为删除,无法读取。✅ 可恢复
软删除 (指定版本)vault kv delete -versions=2 secret/myapp/db标记版本2为删除。✅ 可恢复
恢复已删除版本vault kv undelete -versions=2 secret/myapp/db恢复版本2至可用状态。-
永久销毁版本vault kv destroy -versions=1 secret/myapp/db彻底删除版本1的数据,不可用于解密旧数据。❌ 不可恢复

批量销毁版本

1
vault kv destroy -versions=1,2,3 secret/myapp/db

Clipboard_Screenshot_1766743456

Clipboard_Screenshot_1766743468

五、高级配置:版本保留策略

通过配置秘密的元数据,可以实现自动化的版本生命周期管理。

限制秘密最多保留版本数量

1
vault kv metadata put -max-versions=3 secret/myapp/db

Clipboard_Screenshot_1766743497

Clipboard_Screenshot_1766743510

设置版本自动删除策略

1
2
# 设置每个版本在创建1天后自动删除
vault kv metadata put -delete-version-after="1d" secret/myapp/db

Clipboard_Screenshot_1766743534

Clipboard_Screenshot_1766743551

配置后Vault 将自动清理超过 max-versions 的最旧版本,并对达到时间的版本执行软删除。

、并发控制:Check-And-Set (CAS) 操作

在自动化流程或多个客户端同时尝试更新同一个秘密时,如果不使用版本控制机制,容易发生数据被意外覆盖的竞争条件(Race Condition)

KV v2 引擎通过 Check-And-Set (CAS) 机制解决了这一问题。

CAS 操作要求用户在写入数据时必须提供一个预期的秘密版本号。

CAS 核心机制

预期版本号 (-cas=N)行为说明适用场景
N > 0只有当 Vault 中秘密的当前版本号与 N 完全匹配时,写入操作才会成功。用于更新一个已知版本的秘密,防止覆盖他人同时提交的更改。
N = 0只有当路径下尚不存在任何秘密时(即版本号为 0),写入操作才会成功。用于确保你正在创建新秘密,防止意外覆盖现有数据。
未设置 (-cas标志)正常执行 vault kv put,总是覆盖旧数据并创建新版本。快速更新,但存在并发风险。

操作示例

示例 :安全更新现有秘密 (使用 -cas=N**)**

假设 secret/myapp/db 当前的版本是 3

操作目标: 仅在当前版本确实是 3 的情况下,才将密码更新为 newpass123。

尝试以版本 3 为基础进行更新 (预期成功)

1
2
# 假设你读取了版本 3,并决定更新它
vault kv put -cas=3 secret/myapp/db password="newpass123"

Clipboard_Screenshot_1766743623