シークレットエンジン
KVシークレット
Key-Valueシークレットエンジンの使い方
最終更新: 2026/2/17
KVシークレット
KV(Key-Value)シークレットエンジンは、Vaultで最も基本的なシークレット管理方法です。静的なシークレットを保存・取得するために使用します。
KVシークレットエンジンとは
KVシークレットエンジンは、キーと値のペアでシークレットを保存するシンプルなストレージです。
バージョン
| バージョン | 特徴 | 推奨用途 |
|---|---|---|
| KV v1 | シンプル、バージョン管理なし | レガシーシステム |
| KV v2 | バージョン管理、削除保護 | 新規プロジェクト(推奨) |
KV v2を推奨新規プロジェクトでは、バージョン管理機能を持つKV v2の使用を推奨します。開発サーバーではKV v2がデフォルトで有効化されています。
KV v2の特徴
1. バージョン管理
すべての変更履歴が保存されます。
# バージョン1
vault kv put secret/myapp/config password=old
# バージョン2
vault kv put secret/myapp/config password=new
# バージョン1を取得
vault kv get -version=1 secret/myapp/config
2. 削除保護
削除されたシークレットを復元できます。
# 削除
vault kv delete secret/myapp/config
# 復元
vault kv undelete -versions=2 secret/myapp/config
3. メタデータ管理
シークレットのメタデータを個別に管理できます。
# メタデータを確認
vault kv metadata get secret/myapp/config
シークレットエンジンの有効化
KV v2の有効化
# KV v2を有効化
vault secrets enable -path=secret kv-v2
# カスタムパスで有効化
vault secrets enable -path=myapp kv-v2
KV v1の有効化
# KV v1を有効化
vault secrets enable -path=kv kv
有効化の確認
vault secrets list
出力例:
Path Type Description
---- ---- -----------
cubbyhole/ cubbyhole per-token private secret storage
identity/ identity identity store
secret/ kv key/value secret storage
sys/ system system endpoints used for control, policy and debugging
基本操作(KV v2)
シークレットの保存
# 単一のキー・バリュー
vault kv put secret/myapp/config \
username=admin
# 複数のキー・バリュー
vault kv put secret/myapp/database \
host=db.example.com \
port=5432 \
username=dbuser \
password=dbpass123
シークレットの取得
# すべてのフィールドを取得
vault kv get secret/myapp/config
# 特定のフィールドのみ取得
vault kv get -field=username secret/myapp/config
# JSON形式で取得
vault kv get -format=json secret/myapp/config
シークレットの更新
# 完全な更新(既存の値を上書き)
vault kv put secret/myapp/config \
username=admin \
password=newpassword
# 部分的な更新(他のフィールドは保持)
vault kv patch secret/myapp/config \
password=newpassword
シークレットの削除
# 最新バージョンを削除(復元可能)
vault kv delete secret/myapp/config
# 特定のバージョンを削除
vault kv delete -versions=1,2 secret/myapp/config
# 完全に削除(復元不可)
vault kv destroy -versions=1 secret/myapp/config
# すべてのバージョンとメタデータを削除
vault kv metadata delete secret/myapp/config
シークレットの一覧表示
# パスの一覧
vault kv list secret/
# サブパスの一覧
vault kv list secret/myapp/
バージョン管理
バージョン履歴の確認
# メタデータを取得
vault kv metadata get secret/myapp/config
出力例:
========== Metadata ==========
Key Value
--- -----
cas_required false
created_time 2024-01-15T10:30:45.123456Z
current_version 3
custom_metadata <nil>
delete_version_after 0s
max_versions 0
oldest_version 0
updated_time 2024-01-15T11:45:30.789012Z
====== Version 1 ======
Key Value
--- -----
created_time 2024-01-15T10:30:45.123456Z
deletion_time n/a
destroyed false
====== Version 2 ======
Key Value
--- -----
created_time 2024-01-15T11:00:15.456789Z
deletion_time n/a
destroyed false
====== Version 3 ======
Key Value
--- -----
created_time 2024-01-15T11:45:30.789012Z
deletion_time n/a
destroyed false
特定のバージョンを取得
# バージョン1を取得
vault kv get -version=1 secret/myapp/config
# バージョン2を取得
vault kv get -version=2 secret/myapp/config
バージョンの復元
# 削除されたバージョンを復元
vault kv undelete -versions=1,2 secret/myapp/config
バージョン数の制限
# 最大10バージョンまで保持
vault kv metadata put -max-versions=10 secret/myapp/config
自動削除の設定
# 30日後に自動削除
vault kv metadata put -delete-version-after=720h secret/myapp/config
Check-And-Set(CAS)
CASを使用すると、競合を防ぐことができます。
CASの有効化
# CASを必須にする
vault kv metadata put -cas-required=true secret/myapp/config
CASを使用した更新
# 現在のバージョンを確認
vault kv get secret/myapp/config
# バージョン3を基に更新
vault kv put -cas=3 secret/myapp/config \
username=admin \
password=newpassword
エラー例(バージョンが一致しない場合):
Error writing data to secret/data/myapp/config: Error making API request.
Code: 400. Errors:
* check-and-set parameter did not match the current version
カスタムメタデータ
メタデータの設定
# カスタムメタデータを設定
vault kv metadata put secret/myapp/config \
custom_metadata=owner=team-a \
custom_metadata=environment=production
メタデータの取得
vault kv metadata get secret/myapp/config
実践例
1. 環境ごとの設定管理
# 開発環境
vault kv put secret/myapp/dev \
db_host=dev-db.example.com \
db_username=dev_user \
db_password=dev_pass \
api_endpoint=https://dev-api.example.com
# ステージング環境
vault kv put secret/myapp/staging \
db_host=staging-db.example.com \
db_username=staging_user \
db_password=staging_pass \
api_endpoint=https://staging-api.example.com
# 本番環境
vault kv put secret/myapp/production \
db_host=prod-db.example.com \
db_username=prod_user \
db_password=prod_pass \
api_endpoint=https://api.example.com
2. アプリケーション設定の階層化
# 共通設定
vault kv put secret/myapp/common \
log_level=info \
timeout=30
# サービスA固有の設定
vault kv put secret/myapp/service-a \
port=8080 \
workers=4
# サービスB固有の設定
vault kv put secret/myapp/service-b \
port=8081 \
workers=2
3. 機密情報の分離
# データベース認証情報
vault kv put secret/myapp/database \
host=db.example.com \
username=dbuser \
password=dbpass
# API認証情報
vault kv put secret/myapp/api \
key=sk_live_abc123 \
secret=secret_xyz789
# 証明書
vault kv put secret/myapp/certificates \
tls_cert=@/path/to/cert.pem \
tls_key=@/path/to/key.pem
4. ファイルからの一括登録
# JSONファイルを作成
cat > config.json <<EOF
{
"database": {
"host": "db.example.com",
"port": 5432,
"username": "dbuser",
"password": "dbpass"
},
"api": {
"endpoint": "https://api.example.com",
"key": "sk_live_abc123"
}
}
EOF
# ファイルから登録
vault kv put secret/myapp/config @config.json
APIでの使用
シークレットの保存
curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
--request POST \
--data '{"data":{"username":"admin","password":"secret"}}' \
http://127.0.0.1:8200/v1/secret/data/myapp/config
シークレットの取得
curl \
--header "X-Vault-Token: $VAULT_TOKEN" \
http://127.0.0.1:8200/v1/secret/data/myapp/config
レスポンス:
{
"request_id": "abc123-def456",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"data": {
"password": "secret",
"username": "admin"
},
"metadata": {
"created_time": "2024-01-15T10:30:45.123456Z",
"custom_metadata": null,
"deletion_time": "",
"destroyed": false,
"version": 1
}
}
}
プログラミング言語での使用
Python
import hvac
import os
# Vaultクライアントの初期化
client = hvac.Client(
url=os.environ['VAULT_ADDR'],
token=os.environ['VAULT_TOKEN']
)
# シークレットの保存
client.secrets.kv.v2.create_or_update_secret(
path='myapp/config',
secret=dict(username='admin', password='secret')
)
# シークレットの取得
secret = client.secrets.kv.v2.read_secret_version(path='myapp/config')
username = secret['data']['data']['username']
password = secret['data']['data']['password']
print(f"Username: {username}")
Go
package main
import (
"context"
"fmt"
"log"
"os"
vault "github.com/hashicorp/vault/api"
)
func main() {
// Vaultクライアントの初期化
config := vault.DefaultConfig()
config.Address = os.Getenv("VAULT_ADDR")
client, err := vault.NewClient(config)
if err != nil {
log.Fatal(err)
}
client.SetToken(os.Getenv("VAULT_TOKEN"))
// シークレットの保存
data := map[string]interface{}{
"data": map[string]interface{}{
"username": "admin",
"password": "secret",
},
}
_, err = client.Logical().Write("secret/data/myapp/config", data)
if err != nil {
log.Fatal(err)
}
// シークレットの取得
secret, err := client.Logical().Read("secret/data/myapp/config")
if err != nil {
log.Fatal(err)
}
data = secret.Data["data"].(map[string]interface{})
username := data["username"].(string)
password := data["password"].(string)
fmt.Printf("Username: %s\n", username)
}
Node.js
const vault = require('node-vault')({
apiVersion: 'v1',
endpoint: process.env.VAULT_ADDR,
token: process.env.VAULT_TOKEN
});
// シークレットの保存
async function writeSecret() {
await vault.write('secret/data/myapp/config', {
data: {
username: 'admin',
password: 'secret'
}
});
}
// シークレットの取得
async function readSecret() {
const result = await vault.read('secret/data/myapp/config');
const { username, password } = result.data.data;
console.log(`Username: ${username}`);
}
writeSecret().then(readSecret);
ベストプラクティス
1. 階層的な構造
secret/
├── myapp/
│ ├── common/ # 共通設定
│ ├── dev/ # 開発環境
│ ├── staging/ # ステージング環境
│ └── production/ # 本番環境
└── shared/
└── certificates/ # 共有証明書
2. 命名規則
- 小文字を使用:
myapp/config - ケバブケース:
my-app/db-config - 環境を明示:
myapp/production/database
3. バージョン管理
# 最大バージョン数を制限
vault kv metadata put -max-versions=10 secret/myapp/config
# 古いバージョンを自動削除
vault kv metadata put -delete-version-after=2160h secret/myapp/config
4. アクセス制御
# 読み取り専用ポリシー
path "secret/data/myapp/*" {
capabilities = ["read", "list"]
}
# 読み書き可能ポリシー
path "secret/data/myapp/*" {
capabilities = ["create", "read", "update", "delete", "list"]
}
トラブルシューティング
シークレットが見つからない
エラー:
No value found at secret/data/myapp/config
確認事項:
# パスを確認
vault kv list secret/
vault kv list secret/myapp/
# 正しいパスで取得
vault kv get secret/myapp/config
CASエラー
エラー:
check-and-set parameter did not match the current version
解決策:
# 現在のバージョンを確認
vault kv get secret/myapp/config
# 正しいバージョンで更新
vault kv put -cas=<current-version> secret/myapp/config key=value
バージョンが削除されている
エラー:
deletion_time is set
解決策:
# バージョンを復元
vault kv undelete -versions=<version> secret/myapp/config
次のステップ
KVシークレットの基本を理解したら、次はデータベースシークレットで動的シークレットの生成を学びましょう。
KVシークレットの活用KVシークレットは、静的な設定情報の管理に最適です。パスワードやAPIキーなど、頻繁に変更されない情報を保存するために使用してください。