HashiCorp Vault
HashiCorp Vault シークレットエンジン ウェビナー — デモスクリプト
最終更新: 2026/8/12
HashiCorp Vault シークレットエンジン ウェビナー — デモスクリプト
対象セクション: セクション 5(40–55 分)
目的: CLI と API の両操作で「動的シークレットのライフサイクル」を体験する
事前準備
# Vault Dev Server の起動(ターミナル 1)
vault server -dev -dev-root-token-id=EXAMPLE-root-token
# 別ターミナルで環境変数を設定(ターミナル 2)
export VAULT_ADDR='http://127.0.0.1:8200'
export VAULT_TOKEN='EXAMPLE-root-token'
# Vault の状態確認
vault status
PostgreSQL の起動(Database デモ用)
# Docker で PostgreSQL を起動
docker run -d \
--name vault-demo-postgres \
-e POSTGRES_USER=root \
-e POSTGRES_PASSWORD=EXAMPLE-rootpassword \
-e POSTGRES_DB=mydb \
-p 5432:5432 \
postgres:15
# 接続確認
docker exec -it vault-demo-postgres psql -U root -c "\l"
デモ 1 : KV v2 シークレット管理(約 4 分)
1-1 KV v2 の有効化
# KV v2 シークレットエンジンを有効化
vault secrets enable -path=secret kv-v2
# 確認
vault secrets list
期待出力:
Path Type Accessor Description
---- ---- -------- -----------
cubbyhole/ cubbyhole cubbyhole_... per-token private secret storage
identity/ identity identity_... identity store
secret/ kv kv_... n/a
sys/ system system_... system endpoints used for control ...
1-2 シークレットの保存・取得
# シークレットの保存(v1)
vault kv put secret/myapp/prod \
db_host=prod-db.example.com \
db_port=5432 \
api_key=sk_live_EXAMPLE123def456
# シークレットの取得
vault kv get secret/myapp/prod
# JSON 形式で取得
vault kv get -format=json secret/myapp/prod
# 特定フィールドのみ取得
vault kv get -field=api_key secret/myapp/prod
1-3 バージョン管理のデモ
# シークレットを更新(v2 が作成される)
vault kv put secret/myapp/prod \
db_host=prod-db.example.com \
db_port=5432 \
api_key=sk_live_EXAMPLE_NEW_KEY_789
# バージョン履歴の確認
vault kv metadata get secret/myapp/prod
# バージョン 1(古い値)の取得
vault kv get -version=1 secret/myapp/prod
# 最新バージョン(v2)の取得
vault kv get secret/myapp/prod
1-4 ソフト削除とロールバック
# ソフト削除(復元可能)
vault kv delete secret/myapp/prod
# 削除後に取得しようとするとエラー
vault kv get secret/myapp/prod
# バージョンを復元
vault kv undelete -versions=2 secret/myapp/prod
# 復元後は取得可能
vault kv get secret/myapp/prod
1-5 API でのアクセス(cURL)
# cURL でシークレットを取得
curl \
--header "X-Vault-Token: EXAMPLE-root-token" \
http://127.0.0.1:8200/v1/secret/data/myapp/prod | jq .
# レスポンス構造のポイント説明:
# .data.data → 実際のシークレット値
# .data.metadata → バージョン情報・作成日時
デモ 2 : PKI 証明書の発行(約 3 分)
2-1 PKI エンジンの有効化とルート CA 生成
# PKI エンジンの有効化
vault secrets enable pki
# 最大 TTL を 10 年に設定
vault secrets tune -max-lease-ttl=87600h pki
# ルート CA の生成(自己署名)
vault write pki/root/generate/internal \
common_name="example.com" \
ttl=87600h
# CRL / Issuing CA の URL 設定
vault write pki/config/urls \
issuing_certificates="http://127.0.0.1:8200/v1/pki/ca" \
crl_distribution_points="http://127.0.0.1:8200/v1/pki/crl"
2-2 ロール作成と証明書発行
# ロールの作成
vault write pki/roles/example-dot-com \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="72h"
# 証明書の発行
vault write pki/issue/example-dot-com \
common_name="web.example.com" \
ttl="24h"
発行後に確認する内容:
certificate: 発行された証明書(PEM 形式)private_key: 秘密鍵(PEM 形式)※ 1 回しか表示されないserial_number: 証明書のシリアル番号expiration: 有効期限のタイムスタンプ
# 証明書の内容確認(openssl)
# ※ 証明書を cert.pem に保存してから実行
vault write -field=certificate pki/issue/example-dot-com \
common_name="test.example.com" ttl="1h" > /tmp/cert.pem
openssl x509 -in /tmp/cert.pem -text -noout | grep -E "Subject:|Not Before:|Not After:"
2-3 証明書の失効
# シリアル番号を使って証明書を失効
SERIAL=$(vault write -field=serial_number pki/issue/example-dot-com \
common_name="revoke-test.example.com" ttl="1h")
echo "Serial: $SERIAL"
vault write pki/revoke serial_number="$SERIAL"
# CRL の確認
vault read pki/cert/crl
デモ 3 : Database 動的認証情報(約 5 分)
3-1 Database エンジンの有効化
# Database シークレットエンジンの有効化
vault secrets enable database
3-2 PostgreSQL 接続の設定
# Vault の管理用ユーザーを PostgreSQL に作成
docker exec -it vault-demo-postgres psql -U root -c "
CREATE USER vault WITH SUPERUSER PASSWORD 'EXAMPLE-vaultpassword';
"
# Vault に PostgreSQL 接続設定を書き込む
vault write database/config/my-postgres \
plugin_name=postgresql-database-plugin \
allowed_roles="app-readonly,app-readwrite" \
connection_url="postgresql://{{username}}:{{password}}@127.0.0.1:5432/mydb?sslmode=disable" \
username="vault" \
password="EXAMPLE-vaultpassword"
3-3 ロールの定義
# 読み取り専用ロール(TTL 1h)
vault write database/roles/app-readonly \
db_name=my-postgres \
creation_statements="
CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";
" \
default_ttl="1h" \
max_ttl="24h"
# 読み書きロール(TTL 30m)
vault write database/roles/app-readwrite \
db_name=my-postgres \
creation_statements="
CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO \"{{name}}\";
" \
default_ttl="30m" \
max_ttl="2h"
3-4 動的認証情報の取得(2 回実行して毎回ユニークなことを確認)
# 1 回目
vault read database/creds/app-readonly
# 2 回目(ユーザー名・パスワードが異なることを確認)
vault read database/creds/app-readonly
# PostgreSQL でユーザー一覧を確認(v-token-app-readonly-... が 2 つ見える)
docker exec -it vault-demo-postgres psql -U root -c "\du"
3-5 リースの失効と DB ユーザーの自動削除
# リース ID を保存しながら取得
LEASE_ID=$(vault read -format=json database/creds/app-readonly | jq -r '.lease_id')
echo "Lease ID: $LEASE_ID"
# PostgreSQL でユーザー存在確認
docker exec -it vault-demo-postgres psql -U root -c "\du" | grep "v-token"
# リースを失効
vault lease revoke "$LEASE_ID"
# PostgreSQL でユーザーが削除されていることを確認
docker exec -it vault-demo-postgres psql -U root -c "\du" | grep "v-token"
# → 対象ユーザーが消えている
3-6 ルート認証情報のローテーション
# Vault が使用する管理者パスワードをローテーション
vault write -force database/rotate-root/my-postgres
# ローテーション後、Vault は新しいパスワードを管理し直接確認不可
# データベース接続の動作は継続される
vault read database/creds/app-readonly
デモ 4 : AWS 動的クレデンシャル(約 4 分)
前提: AWS の IAM ユーザー(管理者権限)または AssumeRole 用のロールが存在すること
4-1 AWS エンジンの有効化と設定
# AWS シークレットエンジンの有効化
vault secrets enable aws
# ルート認証情報の設定(iam_user 方式用)
vault write aws/config/root \
access_key=AKIAIOSFODNN7EXAMPLE \
secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
region=ap-northeast-1
4-2 ロールの定義
# IAM ユーザー方式(インラインポリシー:S3 読み取り専用)
vault write aws/roles/s3-reader \
credential_type=iam_user \
policy_document='-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": "*"
}
]
}
EOF'
# Assumed Role 方式(既存 IAM ロールを AssumeRole)
vault write aws/roles/my-assumed-role \
credential_type=assumed_role \
role_arns="arn:aws:iam::123456789012:role/MyVaultRole" \
default_ttl=1h \
max_ttl=4h
4-3 動的クレデンシャルの取得と使用
# IAM ユーザー方式でクレデンシャル取得
vault read aws/creds/s3-reader
# 取得したクレデンシャルを環境変数に設定して AWS CLI で確認
export AWS_ACCESS_KEY_ID="AKIAI44QH8DHBEXAMPLE"
export AWS_SECRET_ACCESS_KEY="je7MtGbClwBF/2Zp9Utk/EXAMPLE..."
# AWS CLI で S3 バケット一覧(権限確認)
aws s3 ls
# AWS IAM で作成されたユーザーを確認
aws iam list-users | grep -i vault
4-4 リース失効とアクセス不可の確認
# リース ID を保存しながら取得
LEASE_ID=$(vault read -format=json aws/creds/s3-reader | jq -r '.lease_id')
# リースを失効
vault lease revoke "$LEASE_ID"
# 同じクレデンシャルで AWS にアクセス → エラーになる
aws s3 ls
# Error: An error occurred (InvalidClientTokenId) when calling the ListBuckets operation
デモ後の補足ポイント(Q&A 用)
| 質問 | 回答のポイント |
|---|---|
| 漏洩時の対応は? | vault lease revoke -prefix <path> で一括失効。全 DB ユーザー・IAM ユーザーを即座に削除可能。 |
| アプリから自動で使うには? | Vault Agent / SDK(hvac, vault-go)でリース自動更新。Kubernetes では Vault Agent Injector。 |
| パスワードが見えなくなる方法は? | vault secrets tune で TTL を短くし、監査ログの HMAC マスクを活用。 |
| 静的 vs 動的はどう選ぶ? | 外部 API キーなど Vault が生成できない = KV、DB/クラウドなど Vault が生成できる = 動的シークレット。 |
| PKI の証明書はどのくらい短命にすべき? | 内部サービス間なら数時間〜1日。頻繁な自動更新が前提なら 1〜7 日が現実的。 |
このスクリプトは content/vault/webinar_secrets_engine_demo_script.md に保存されています。