Vault 的 kv-v2 引擎必须启用版本化才能轮转,因其唯一支持历史版本保留,轮转即写入新版本并更新引用;误用 kv-v1 会导致覆盖旧值、无法回滚或审计。

Vault 的 kv-v2 引擎必须启用版本化才能轮转
kv-v2 是唯一支持历史版本保留的引擎,轮转本质就是写入新版本、更新引用。如果误用 kv-v1(默认不带版本号),write 操作会覆盖旧值,无法回滚或审计变更。启用时路径必须显式指定 kv-v2:
vault secrets enable -version=2 -path=secret kv
确认是否生效:vault kv get -version=1 secret/db 和 vault kv get -version=2 secret/db 应返回不同结构(后者含 metadata 字段)。
用 Vault Agent Auto-Auth + Template 实现密码自动注入
中间件本身不支持 Vault 认证时,靠 vault-agent 在启动前拉取并渲染配置。关键不是“轮转时改中间件”,而是“每次重启/重载都用最新版本”。需注意:
-
vault-agent配置中auto_auth必须用可刷新凭证(如jwt或token),不能硬编码 root token -
template中必须用{{ with secret "secret/data/db" }}{{ .Data.data.password }}{{ end }}—— 注意data/db而非db,因为 kv-v2 的实际数据在data子路径下 - 模板文件需设为只读,防止中间件意外覆盖;
vault-agent默认每 5s 检查一次变更,但不会自动 reload 进程,需配合exec或 systemd notify
用 Vault 的 rotation policy + periodic job 触发轮转
Vault 本身不主动轮转密码,需外部调度调用 vault kv put。常见做法是用 cron + shell 脚本,但要注意三点:
- 轮转脚本必须生成强随机密码:
openssl rand -base64 24 | tr '+/' '-_' | tr -d '\n'(避免特殊字符导致中间件解析失败) - 写入时必须指定
-field=password并使用secret/data/db路径,否则 kv-v2 不识别为数据字段 - 轮转后需触发中间件 reload:比如对 PostgreSQL,执行
pg_ctl reload -D /var/lib/postgresql/data;对 Nginx,用nginx -s reload—— 这步漏掉就等于没轮转
权限控制必须精确到 path + capability,不能只靠 token
给中间件用的 Vault token 权限若过大,轮转脚本一旦被劫持就会引发越权。正确做法是:
- 为轮转脚本创建专用策略,仅允许
create, update, read在secret/data/db路径 - 为中间件 agent 创建另一策略,仅允许
read,且限定max_ttl = 1h - 禁止策略中出现
sudo或list权限 ——list secret/可能暴露其他路径名,构成信息泄露
轮转逻辑看似简单,真正难的是让“密码变”和“服务用上新密码”之间不出现时间差,以及确保每次轮转都落在最小权限边界内。这两个点一旦松动,自动轮转反而会放大风险。











