紹介します
KV (Key-Value) Secrets Engine は HashiCorp Vault で最も人気のあるシークレット エンジンであり、静的シークレット (API キー、データベース パスワード、構成値、証明書など、時間の経過とともに自動的に変更されないシークレット) を保存および管理するために使用されます。
このレッスンでは、KV v1 と KV v2 の 2 つのバージョン、CRUD 操作、バージョン管理、メタデータ管理、およびその他の多くの高度な機能を実行する方法について詳しく学びます。
1. KV v1 と KV v2 — 詳細な比較
###1.1.違いの概要
| 特長 | KV v1 | KV v2 |
|---|---|---|
| バージョン管理 | ❌ サポートされていません | ✅ フルサポート |
| 論理的な削除 | ❌ 完全に削除されました | ✅ 論理的な削除 + 削除の取り消し |
| メタデータ | ❌ なし | ✅ カスタムメタデータ |
| チェックアンドセット (CAS) | ❌ なし | ✅ サポート |
| パッチ操作 | ❌ なし | ✅ サポート (v1.10 以降) |
| パフォーマンス | ✅ より高速 (シンプル) | わずかに遅い (バージョン管理のため) |
| ストレージの設置面積 | ✅ 小さい | 大きい (複数のバージョンを保存) |
###1.2. KV v1 をいつ使用するか?
- 最大のパフォーマンスが必要で、バージョン管理が必要ない場合
- 保管が重要な要素の場合
- シークレットの場合、変更は非常にまれです
###1.3. KV v2 をいつ使用するか?
- ほとんどの使用例 (デフォルトを推奨)
- バージョン履歴の監査証跡が必要な場合
- 古いバージョンにロールバックする機能が必要な場合
- 安全性を高めるために論理的な削除が必要な場合
2. KV シークレット エンジンを有効にして構成する
###2.1. KV v1 を有効にする
# Enable KV v1 tại path kv-v1/
vault secrets enable -path=kv-v1 -version=1 kv
# Xác nhận engine đã được enable
vault secrets list
# Output mẫu:
# Path Type Accessor Description
# ---- ---- -------- -----------
# kv-v1/ kv kv_a1b2c3d4 n/a
# secret/ kv kv_e5f6g7h8 key/value secret storage
###2.2. KV v2 を有効にする
# Enable KV v2 tại path kv-v2/
vault secrets enable -path=kv-v2 -version=2 kv
# Hoặc sử dụng API
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"type": "kv", "options": {"version": "2"}}' \
"$VAULT_ADDR/v1/sys/mounts/kv-v2"
注意: Vault dev サーバーを起動すると、デフォルトの
secret/パスはすでに KV v2 になっています。
###2.3. KV v2 の構成
# Cấu hình KV v2 — giới hạn max versions và CAS required
vault write kv-v2/config \
max_versions=10 \
cas_required=false \
delete_version_after="768h"
# Đọc cấu hình hiện tại
vault read kv-v2/config
# Output:
# Key Value
# --- -----
# cas_required false
# delete_version_after 768h0m0s
# max_versions 10
重要な構成:
- max_versions: 保持するバージョンの最大数 (0 = 無制限)
- cas_required: すべての書き込み操作にチェックアンドセットが必要です
- delete_version_after: 一定期間後にバージョンを自動的に削除します
3. CRUD 操作 — 基本操作
###3.1.シークレットの作成と記録 (作成/更新)
KV v1
# Tạo secret mới
vault kv put kv-v1/myapp/database \
username="admin" \
password="P@ssw0rd2024!"
# ⚠️ KV v1: Ghi đè TOÀN BỘ secret, không merge
vault kv put kv-v1/myapp/database \
username="admin" \
password="NewP@ss2024!" \
host="db.example.com"
KV v2
# Tạo secret mới
vault kv put kv-v2/myapp/database \
username="admin" \
password="P@ssw0rd2024!" \
host="db.example.com" \
port="5432"
# Output:
# ========= Secret Path =========
# kv-v2/data/myapp/database
#
# ======= Metadata =======
# Key Value
# --- -----
# created_time 2024-01-15T10:30:00.123456Z
# custom_metadata <nil>
# deletion_time n/a
# destroyed false
# version 1
# Cập nhật secret — tạo version 2
vault kv put kv-v2/myapp/database \
username="admin" \
password="UpdatedP@ss!" \
host="db.example.com" \
port="5432"
ファイルからシークレットを書き込む
# Tạo file JSON chứa secret
cat > /tmp/db-secret.json << 'EOF'
{
"username": "admin",
"password": "S3cur3P@ssw0rd!",
"host": "primary-db.internal",
"port": "5432",
"database": "myapp_production",
"ssl_mode": "require"
}
EOF
# Ghi secret từ file
vault kv put kv-v2/myapp/database @/tmp/db-secret.json
# Xóa file tạm ngay sau khi sử dụng
rm -f /tmp/db-secret.json
```###3.2.シークレットの読み取り (読み取り)
```bash
# Đọc version mới nhất
vault kv get kv-v2/myapp/database
# Output:
# ========= Secret Path =========
# kv-v2/data/myapp/database
#
# ======= Metadata =======
# Key Value
# --- -----
# created_time 2024-01-15T10:35:00.654321Z
# custom_metadata <nil>
# deletion_time n/a
# destroyed false
# version 2
#
# ====== Data ======
# Key Value
# --- -----
# database myapp_production
# host primary-db.internal
# password S3cur3P@ssw0rd!
# port 5432
# ssl_mode require
# username admin
# Đọc version cụ thể
vault kv get -version=1 kv-v2/myapp/database
# Chỉ đọc một field cụ thể
vault kv get -field=password kv-v2/myapp/database
# Đọc dưới dạng JSON
vault kv get -format=json kv-v2/myapp/database
# Sử dụng jq để extract
vault kv get -format=json kv-v2/myapp/database | jq -r '.data.data.password'
###3.3.シークレットをリストする
# List tất cả keys tại một path
vault kv list kv-v2/myapp/
# Output:
# Keys
# ----
# database
# redis
# smtp
# List sử dụng API
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request LIST \
"$VAULT_ADDR/v1/kv-v2/metadata/myapp"
###3.4.シークレットの削除(削除)
# Soft delete version mới nhất (KV v2)
vault kv delete kv-v2/myapp/database
# Soft delete version cụ thể
vault kv delete -versions=1,2 kv-v2/myapp/database
4. バージョニング — バージョン管理
###4.1. Xemのバージョン履歴
# Đọc metadata — bao gồm tất cả version info
vault kv metadata get kv-v2/myapp/database
# Output:
# ========== Metadata ==========
# Key Value
# --- -----
# cas_required false
# created_time 2024-01-15T10:30:00.123456Z
# current_version 3
# custom_metadata <nil>
# delete_version_after 0s
# max_versions 0
# oldest_version 1
# updated_time 2024-01-15T11:00:00.789012Z
#
# ====== Version 1 ======
# Key Value
# --- -----
# created_time 2024-01-15T10:30:00.123456Z
# deletion_time n/a
# destroyed false
#
# ====== Version 2 ======
# Key Value
# --- -----
# created_time 2024-01-15T10:35:00.654321Z
# deletion_time n/a
# destroyed false
#
# ====== Version 3 ======
# Key Value
# --- -----
# created_time 2024-01-15T11:00:00.789012Z
# deletion_time n/a
# destroyed false
###4.2.古いバージョンにロールバックする
# Đọc version 1
vault kv get -format=json -version=1 kv-v2/myapp/database | \
jq '.data.data' | \
vault kv put kv-v2/myapp/database -
# Giờ version 4 sẽ có nội dung giống version 1
###4.3.バージョンの帰属 (Vault 1.21+)
Vault 1.21 以降、各バージョンには、そのバージョンの 作成者 に関する情報が記録されます。
# Đọc metadata với version attribution
vault kv metadata get -format=json kv-v2/myapp/database | \
jq '.data.versions'
# Output (Vault 1.21+):
# {
# "1": {
# "created_time": "2024-01-15T10:30:00.123456Z",
# "created_by": {
# "display_name": "token-admin",
# "entity_id": "abc123...",
# "policies": ["admin", "default"]
# },
# ...
# }
# }
5. チェックアンドセット (CAS)
CAS は、複数のクライアントが同じシークレットに書き込むときの 競合状態 を防ぐのに役立ちます。
###5.1.マウント全体で CAS を有効にする
vault write kv-v2/config cas_required=true
###5.2.録画時に CAS を使用する
# Ghi với CAS — phải chỉ định version hiện tại
# cas=0 nghĩa là tạo mới (secret chưa tồn tại)
vault kv put -cas=0 kv-v2/myapp/new-secret key="value"
# Cập nhật — cas phải bằng version hiện tại
vault kv put -cas=1 kv-v2/myapp/new-secret key="updated-value"
# Nếu version không khớp → lỗi
vault kv put -cas=1 kv-v2/myapp/new-secret key="another-value"
# Error: check-and-set parameter did not match the current version
###5.3.キーごとの CAS
# Đặt CAS required cho một key cụ thể
vault kv metadata put -cas-required=true kv-v2/myapp/critical-secret
6. 論理的な削除、削除の取り消し、および破棄
###6.1.ソフト削除
# Soft delete — dữ liệu vẫn tồn tại nhưng bị đánh dấu đã xóa
vault kv delete kv-v2/myapp/database
# Đọc sẽ thấy thông báo đã xóa
vault kv get kv-v2/myapp/database
# No value found at kv-v2/data/myapp/database
# Soft delete versions cụ thể
vault kv delete -versions=1,3 kv-v2/myapp/database
###6.2.削除の取り消し - 復元
# Khôi phục version đã soft delete
vault kv undelete -versions=1 kv-v2/myapp/database
# Giờ có thể đọc lại version 1
vault kv get -version=1 kv-v2/myapp/database
###6.3.破棄 — 完全に削除します
# Destroy version cụ thể — KHÔNG THỂ khôi phục
vault kv destroy -versions=1,2 kv-v2/myapp/database
# Xóa toàn bộ key và tất cả versions + metadata
vault kv metadata delete kv-v2/myapp/database
警告:
destroyおよびmetadata deleteは元に戻すことができないアクションです。削除する前に、本当に完全に削除してもよいかどうかを確認してください。
7. パッチ操作
Vault 1.10 以降では、シークレット全体を上書きせずに 一部のフィールドを更新できます。
###7.1.フィールドにパッチを適用する
# Secret hiện tại có: username, password, host, port
# Chỉ cập nhật password mà giữ nguyên các fields khác
vault kv patch kv-v2/myapp/database password="BrandNewP@ss!"
# Kiểm tra — các fields khác vẫn intact
vault kv get kv-v2/myapp/database
###7.2. CAS によるパッチ
# Patch với check-and-set
vault kv patch -cas=5 kv-v2/myapp/database password="AnotherP@ss!"
###7.3. API によるパッチ
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--header "Content-Type: application/merge-patch+json" \
--request PATCH \
--data '{"data": {"password": "APIUpdatedP@ss!"}}' \
"$VAULT_ADDR/v1/kv-v2/data/myapp/database"
8. カスタムメタデータ
カスタム メタデータを使用すると、シークレット データに影響を与えることなく追加情報をシークレットに添付できます。
# Thêm custom metadata
vault kv metadata put \
-custom-metadata=owner="team-platform" \
-custom-metadata=environment="production" \
-custom-metadata=rotation-schedule="90d" \
-custom-metadata=jira-ticket="SEC-1234" \
kv-v2/myapp/database
# Đọc metadata
vault kv metadata get kv-v2/myapp/database
# Output sẽ hiển thị:
# custom_metadata map[environment:production jira-ticket:SEC-1234 owner:team-platform rotation-schedule:90d]
# Cập nhật max_versions cho key cụ thể
vault kv metadata put -max-versions=5 kv-v2/myapp/database
# Cấu hình tự động xóa version sau 30 ngày
vault kv metadata put -delete-version-after="720h" kv-v2/myapp/database
9. KV v1 から KV v2 への移行
###9.1.直接アップグレード (インプレース)
# Kiểm tra version hiện tại
vault read sys/mounts/kv-v1
# Upgrade từ v1 sang v2
vault kv enable-versioning kv-v1/
# Xác nhận đã upgrade thành công
vault read sys/mounts/kv-v1
# options map[version:2]
重要な注意事項: アップグレード プロセスは 一方向です。v2 から v1 にダウングレードすることはできません。
###9.2.新しいマウントへの移行
v1 を保持し、v2 にコピーを作成する場合は、次のようにします。
#!/bin/bash
# Script migration KV v1 sang KV v2
SOURCE="kv-v1"
DEST="kv-v2"
# Function để migrate đệ quy
migrate_path() {
local path="$1"
# List tất cả keys tại path
local keys
keys=$(vault kv list -format=json "${SOURCE}/${path}" 2>/dev/null | jq -r '.[]')
for key in $keys; do
if [[ "$key" == */ ]]; then
# Đây là folder, đệ quy vào
migrate_path "${path}${key}"
else
# Đây là secret, copy sang v2
echo "Migrating: ${path}${key}"
vault kv get -format=json "${SOURCE}/${path}${key}" | \
jq '.data' | \
vault kv put "${DEST}/${path}${key}" -
fi
done
}
# Bắt đầu migration từ root
migrate_path ""
echo "Migration complete!"
###9.3.移行後の確認
# So sánh số lượng keys
echo "KV v1 keys:"
vault kv list -format=json kv-v1/myapp/ | jq length
echo "KV v2 keys:"
vault kv list -format=json kv-v2/myapp/ | jq length
# Spot check một secret
echo "=== V1 ==="
vault kv get -format=json kv-v1/myapp/database | jq '.data'
echo "=== V2 ==="
vault kv get -format=json kv-v2/myapp/database | jq '.data.data'
10. API リファレンス — 重要なエンドポイント
10.1。 KV v2 API エンドポイント
# Ghi secret
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"data": {"username": "admin", "password": "secret"}}' \
"$VAULT_ADDR/v1/kv-v2/data/myapp/database"
# Đọc secret
curl --header "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/kv-v2/data/myapp/database"
# Đọc version cụ thể
curl --header "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/kv-v2/data/myapp/database?version=2"
# Đọc metadata
curl --header "X-Vault-Token: $VAULT_TOKEN" \
"$VAULT_ADDR/v1/kv-v2/metadata/myapp/database"
# Soft delete versions
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"versions": [1, 2]}' \
"$VAULT_ADDR/v1/kv-v2/delete/myapp/database"
# Undelete versions
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"versions": [1, 2]}' \
"$VAULT_ADDR/v1/kv-v2/undelete/myapp/database"
# Destroy versions
curl --header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"versions": [1, 2]}' \
"$VAULT_ADDR/v1/kv-v2/destroy/myapp/database"
11. ベストプラクティス
11.1。パス構造
kv-v2/
├── shared/ # Secrets dùng chung
│ ├── certificates/
│ └── api-keys/
├── teams/
│ ├── platform/
│ │ ├── production/
│ │ └── staging/
│ └── backend/
│ ├── production/
│ └── staging/
└── services/
├── payment-service/
└── auth-service/
###11.2.ポリシーチョー KV v2
# Policy cho team backend — chỉ đọc production secrets
path "kv-v2/data/teams/backend/production/*" {
capabilities = ["read"]
}
# Full access cho staging
path "kv-v2/data/teams/backend/staging/*" {
capabilities = ["create", "read", "update", "delete"]
}
path "kv-v2/metadata/teams/backend/staging/*" {
capabilities = ["list", "read"]
}
# Không cho phép destroy trong production
path "kv-v2/destroy/teams/backend/production/*" {
capabilities = ["deny"]
}
###11.3.導入チェックリスト
- ✅ 新しいプロジェクトには常に KV v2 を使用してください
- ✅ 適切な
max_versions構成 (5 ~ 10 が妥当です) - ✅ 重要なシークレットに対して CAS を有効にする
- ✅ カスタムメタデータを使用して所有権を追跡する
- ✅
delete_version_afterを自動的にクリーンアップするように設定します - ✅ チーム/環境/サービスごとにパスを整理します
- ✅
destroy機能の強力な生産を制限します
概要
このレッスンでは、次のことを習得しました。
- KV v1 と v2 の違い、および各タイプをいつ使用するか
- CLI と API の両方を使用した完全な CRUD 操作
- バージョン管理 — 管理、ロールバック、およびバージョンの帰属
- チェックアンドセット (CAS) による競合状態の回避
- 論理的な削除、削除の取り消し、破棄 — さまざまなレベルの削除
- パッチ操作による部分更新
- カスタム メタデータによる情報の充実
- v1 → v2 の移行は安全です
次の記事では、Database Secrets Engine について説明します。Vault は動的認証情報を自動的に生成する機能を備えています。