シークレットエンジン

動的シークレット

動的シークレットの概念と活用
最終更新: 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の最も強力な機能です。短期間の認証情報により、セキュリティを大幅に向上させることができます。
© 2026 IBM Corporation. Licensed under CC BY 4.0.