シークレットエンジン
動的シークレット
動的シークレットの概念と活用
最終更新: 2026/2/17
動的シークレット
動的シークレットは、Vaultの最も強力な機能の一つです。必要に応じてシークレットを生成し、使用後は自動的に失効させることで、セキュリティを大幅に向上させます。
動的シークレットとは
動的シークレットは、リクエスト時にVaultが生成する一時的なシークレットです。
静的シークレットとの比較
| 特徴 | 静的シークレット | 動的シークレット |
|---|---|---|
| 生成 | 手動で作成 | 自動生成 |
| 有効期限 | 無期限または長期間 | 短期間(分〜時間) |
| ローテーション | 手動 | 自動 |
| 漏洩時の影響 | 大きい | 小さい |
| 管理の複雑さ | シンプル | やや複雑 |
動的シークレットのライフサイクル
1. リクエスト → Vault: シークレットを要求
2. Vault: シークレットを生成
3. Vault → リクエスト: シークレットとリースを返却
4. リクエスト: シークレットを使用
5. リース期限切れ → Vault: シークレットを自動失効
動的シークレットの種類
1. データベース認証情報
用途: データベースへの一時的なアクセス
# PostgreSQL認証情報の生成
vault read database/creds/my-role
Key Value
--- -----
lease_id database/creds/my-role/abc123
lease_duration 1h
username v-token-my-role-x4xd9n8ut
password A1a-BbC2cD3d4eF5g
詳細はデータベースシークレットをご覧ください。
2. AWS認証情報
用途: AWSリソースへの一時的なアクセス
# AWSシークレットエンジンの有効化
vault secrets enable aws
# AWS認証情報の設定
vault write aws/config/root \
access_key=AKIAIOSFODNN7EXAMPLE \
secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \
region=ap-northeast-1
# ロールの作成
vault write aws/roles/my-role \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
EOF
# 動的な認証情報を生成
vault read aws/creds/my-role
Key Value
--- -----
lease_id aws/creds/my-role/abc123
lease_duration 1h
access_key AKIAI44QH8DHBEXAMPLE
secret_key je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
3. SSH証明書
用途: SSHサーバーへの一時的なアクセス
# SSHシークレットエンジンの有効化
vault secrets enable ssh
# CAキーの生成
vault write ssh/config/ca generate_signing_key=true
# ロールの作成
vault write ssh/roles/my-role \
key_type=ca \
ttl=30m \
allow_user_certificates=true \
allowed_users="*" \
default_extensions="permit-pty="
# SSH証明書の生成
vault write ssh/sign/my-role \
public_key=@$HOME/.ssh/id_rsa.pub
Key Value
--- -----
serial_number abc123def456
signed_key ssh-rsa-cert-v01@openssh.com AAAAHHNza...
4. PKI証明書
用途: TLS/SSL証明書の動的発行
# PKIシークレットエンジンの有効化
vault secrets enable pki
# ルートCAの生成
vault write pki/root/generate/internal \
common_name="example.com" \
ttl=87600h
# ロールの作成
vault write pki/roles/example-dot-com \
allowed_domains="example.com" \
allow_subdomains=true \
max_ttl="720h"
# 証明書の発行
vault write pki/issue/example-dot-com \
common_name="test.example.com" \
ttl="24h"
Key Value
--- -----
certificate -----BEGIN CERTIFICATE-----...
issuing_ca -----BEGIN CERTIFICATE-----...
private_key -----BEGIN RSA PRIVATE KEY-----...
serial_number 39:dd:2e:90:b7:23:1f:8d
5. Azure認証情報
用途: Azureリソースへの一時的なアクセス
# Azureシークレットエンジンの有効化
vault secrets enable azure
# Azure認証情報の設定
vault write azure/config \
subscription_id=<subscription-id> \
tenant_id=<tenant-id> \
client_id=<client-id> \
client_secret=<client-secret>
# ロールの作成
vault write azure/roles/my-role \
ttl=1h \
azure_roles=-<<EOF
[
{
"role_name": "Contributor",
"scope": "/subscriptions/<subscription-id>/resourceGroups/my-resource-group"
}
]
EOF
# 動的な認証情報を生成
vault read azure/creds/my-role
6. GCP認証情報
用途: GCPリソースへの一時的なアクセス
# GCPシークレットエンジンの有効化
vault secrets enable gcp
# GCP認証情報の設定
vault write gcp/config \
credentials=@/path/to/credentials.json
# ロールセットの作成
vault write gcp/roleset/my-roleset \
project="my-project" \
secret_type="access_token" \
token_scopes="https://www.googleapis.com/auth/cloud-platform" \
bindings=-<<EOF
resource "//cloudresourcemanager.googleapis.com/projects/my-project" {
roles = ["roles/viewer"]
}
EOF
# 動的な認証情報を生成
vault read gcp/token/my-roleset
リースの管理
リースの概念
リースは、動的シークレットの有効期限を管理する仕組みです。
vault read database/creds/my-role
Key Value
--- -----
lease_id database/creds/my-role/abc123-def456
lease_duration 1h
lease_renewable true
重要なフィールド:
lease_id: リースの一意な識別子lease_duration: 残りの有効期限(秒)lease_renewable: 更新可能かどうか
リースの更新
# リースを更新
vault lease renew database/creds/my-role/abc123-def456
# 特定の期間で更新
vault lease renew -increment=2h database/creds/my-role/abc123-def456
リースの失効
# 特定のリースを失効
vault lease revoke database/creds/my-role/abc123-def456
# プレフィックスに一致するすべてのリースを失効
vault lease revoke -prefix database/creds/my-role/
# すべてのリースを失効(緊急時)
vault lease revoke -prefix /
実践例
1. アプリケーションでの動的シークレット使用
Python例:
import hvac
import psycopg2
import time
import threading
class VaultDatabaseClient:
def __init__(self, vault_url, vault_token, role_name):
self.client = hvac.Client(url=vault_url, token=vault_token)
self.role_name = role_name
self.lease_id = None
self.credentials = None
self.renew_thread = None
def get_credentials(self):
"""動的な認証情報を取得"""
response = self.client.secrets.database.generate_credentials(
name=self.role_name
)
self.lease_id = response['lease_id']
self.credentials = {
'username': response['data']['username'],
'password': response['data']['password']
}
# 自動更新を開始
self.start_renewal()
return self.credentials
def start_renewal(self):
"""リースの自動更新を開始"""
def renew_lease():
while True:
time.sleep(1800) # 30分ごとに更新
try:
self.client.sys.renew_lease(lease_id=self.lease_id)
print("Lease renewed successfully")
except Exception as e:
print(f"Failed to renew lease: {e}")
# 新しい認証情報を取得
self.get_credentials()
self.renew_thread = threading.Thread(target=renew_lease, daemon=True)
self.renew_thread.start()
def connect_database(self):
"""データベースに接続"""
if not self.credentials:
self.get_credentials()
return psycopg2.connect(
host='postgres',
database='mydb',
user=self.credentials['username'],
password=self.credentials['password']
)
# 使用例
vault_client = VaultDatabaseClient(
vault_url='http://vault:8200',
vault_token='hvs.CAESIJ...',
role_name='my-role'
)
conn = vault_client.connect_database()
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()
2. CI/CDパイプラインでの使用
GitHub Actionsの例:
name: Deploy with Dynamic Secrets
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Vaultから動的なAWS認証情報を取得
- name: Get AWS Credentials
id: aws-creds
run: |
VAULT_TOKEN=$(curl -s --request POST \
--data "{\"role_id\":\"${{ secrets.VAULT_ROLE_ID }}\",\"secret_id\":\"${{ secrets.VAULT_SECRET_ID }}\"}" \
${{ secrets.VAULT_ADDR }}/v1/auth/approle/login | jq -r '.auth.client_token')
AWS_CREDS=$(curl -s --header "X-Vault-Token: $VAULT_TOKEN" \
${{ secrets.VAULT_ADDR }}/v1/aws/creds/my-role)
echo "::add-mask::$(echo $AWS_CREDS | jq -r '.data.access_key')"
echo "::add-mask::$(echo $AWS_CREDS | jq -r '.data.secret_key')"
echo "AWS_ACCESS_KEY_ID=$(echo $AWS_CREDS | jq -r '.data.access_key')" >> $GITHUB_ENV
echo "AWS_SECRET_ACCESS_KEY=$(echo $AWS_CREDS | jq -r '.data.secret_key')" >> $GITHUB_ENV
echo "LEASE_ID=$(echo $AWS_CREDS | jq -r '.lease_id')" >> $GITHUB_ENV
# デプロイ処理
- name: Deploy to AWS
run: |
aws s3 sync ./build s3://my-bucket/
# リースを失効
- name: Revoke Lease
if: always()
run: |
curl -s --request PUT \
--header "X-Vault-Token: $VAULT_TOKEN" \
--data "{\"lease_id\":\"$LEASE_ID\"}" \
${{ secrets.VAULT_ADDR }}/v1/sys/leases/revoke
3. Kubernetes環境での使用
Vault Agent Injectorの例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "myapp"
vault.hashicorp.com/agent-inject-secret-database: "database/creds/my-role"
vault.hashicorp.com/agent-inject-template-database: |
{{- with secret "database/creds/my-role" -}}
export DB_USERNAME="{{ .Data.username }}"
export DB_PASSWORD="{{ .Data.password }}"
{{- end }}
spec:
containers:
- name: myapp
image: myapp:latest
command: ["/bin/sh"]
args:
- -c
- |
source /vault/secrets/database
./myapp
ベストプラクティス
1. 短いTTL
# 可能な限り短いTTLを設定
vault write database/roles/my-role \
db_name=my-postgresql-database \
creation_statements="..." \
default_ttl="30m" \
max_ttl="2h"
2. 自動更新の実装
# リースの自動更新
def auto_renew_lease(client, lease_id, interval=1800):
while True:
time.sleep(interval)
try:
client.sys.renew_lease(lease_id=lease_id)
except Exception as e:
# 更新失敗時は新しい認証情報を取得
get_new_credentials()
3. 使用後の即座な失効
# 使用後は即座に失効
vault lease revoke database/creds/my-role/abc123-def456
4. 監査ログの確認
# 動的シークレットの生成を監査
grep "database/creds" /var/log/vault/audit.log
動的シークレットの利点
セキュリティ
✅ 短期間の有効期限
- デフォルト1時間
- 漏洩時の影響を最小化
✅ 自動的なローテーション
- 手動でのパスワード変更不要
- 人的ミスを削減
✅ 完全な監査証跡
- 誰がいつアクセスしたか記録
- コンプライアンス対応
運用
✅ 管理の簡素化
- パスワード管理不要
- 自動的なクリーンアップ
✅ スケーラビリティ
- 多数のアプリケーションに対応
- 自動化に適している
トラブルシューティング
リースの更新に失敗
エラー:
Error renewing lease: lease not found or lease is not renewable
解決策:
# 新しい認証情報を取得
vault read database/creds/my-role
シークレットが生成されない
エラー:
Error reading database/creds/my-role: permission denied
確認事項:
# ポリシーを確認
vault token lookup
# ロールが存在するか確認
vault list database/roles
リースが自動失効しない
確認事項:
# リース情報を確認
vault lease lookup database/creds/my-role/abc123-def456
# 手動で失効
vault lease revoke database/creds/my-role/abc123-def456
次のステップ
動的シークレットを理解したら、次はポリシーの構文でアクセス制御の詳細を学びましょう。
動的シークレットの活用動的シークレットは、Vaultの最も強力な機能です。短期間の認証情報により、セキュリティを大幅に向上させることができます。