シークレットエンジン
データベースシークレット
データベース認証情報の動的生成
最終更新: 2026/2/17
データベースシークレット
データベースシークレットエンジンは、データベース認証情報を動的に生成します。従来の固定パスワードと比べて、セキュリティを大幅に向上させることができます。
データベースシークレットエンジンとは
データベースシークレットエンジンは、必要に応じてデータベースの一時的な認証情報を生成するシークレットエンジンです。
従来の方法との比較
従来の方法:
アプリケーション → 固定のユーザー名/パスワード → データベース
問題点:
- 認証情報が長期間有効
- 漏洩時の影響が大きい
- ローテーションが困難
- 誰がいつアクセスしたか追跡困難
Vaultを使用:
アプリケーション → Vault → 一時的な認証情報生成 → データベース
↓
有効期限後に自動削除
メリット:
- 短期間の認証情報(デフォルト1時間)
- 自動的なローテーション
- 漏洩時の影響を最小化
- 完全な監査証跡
サポートされるデータベース
| データベース | プラグイン名 | 特徴 |
|---|---|---|
| PostgreSQL | postgresql-database-plugin | 完全サポート |
| MySQL/MariaDB | mysql-database-plugin | 完全サポート |
| MongoDB | mongodb-database-plugin | 完全サポート |
| Oracle | oracle-database-plugin | Enterprise版 |
| MSSQL | mssql-database-plugin | 完全サポート |
| Cassandra | cassandra-database-plugin | 完全サポート |
| Elasticsearch | elasticsearch-database-plugin | 完全サポート |
| Redis | redis-database-plugin | 完全サポート |
シークレットエンジンの有効化
# データベースシークレットエンジンを有効化
vault secrets enable database
出力:
Success! Enabled the database secrets engine at: database/
PostgreSQLの設定例
1. データベース接続の設定
# PostgreSQL接続を設定
vault write database/config/my-postgresql-database \
plugin_name=postgresql-database-plugin \
allowed_roles="my-role,readonly-role" \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb?sslmode=disable" \
username="vault" \
password="vault-password"
パラメータの説明:
plugin_name: 使用するプラグインallowed_roles: 許可するロール名connection_url: データベース接続URL({{username}}と{{password}}はプレースホルダー)username: Vaultが使用する管理者ユーザーpassword: 管理者パスワード
2. ロールの作成
# 読み書き可能なロール
vault write database/roles/my-role \
db_name=my-postgresql-database \
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="1h" \
max_ttl="24h"
パラメータの説明:
db_name: データベース接続名creation_statements: ユーザー作成時に実行するSQLdefault_ttl: デフォルトの有効期限max_ttl: 最大有効期限
3. 読み取り専用ロール
# 読み取り専用ロール
vault write database/roles/readonly-role \
db_name=my-postgresql-database \
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"
4. 認証情報の生成
# 動的な認証情報を生成
vault read database/creds/my-role
出力:
Key Value
--- -----
lease_id database/creds/my-role/abc123-def456
lease_duration 1h
lease_renewable true
password A1a-BbC2cD3d4eF5g
username v-token-my-role-x4xd9n8ut92dxv93kd9j-1704067200
重要なフィールド:
lease_id: リースの識別子lease_duration: 有効期限username: 生成されたユーザー名password: 生成されたパスワード
MySQLの設定例
1. データベース接続の設定
# MySQL接続を設定
vault write database/config/my-mysql-database \
plugin_name=mysql-database-plugin \
allowed_roles="my-role" \
connection_url="{{username}}:{{password}}@tcp(mysql:3306)/" \
username="vault" \
password="vault-password"
2. ロールの作成
# MySQLロール
vault write database/roles/my-role \
db_name=my-mysql-database \
creation_statements="CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}'; \
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO '{{name}}'@'%';" \
default_ttl="1h" \
max_ttl="24h"
MongoDBの設定例
1. データベース接続の設定
# MongoDB接続を設定
vault write database/config/my-mongodb-database \
plugin_name=mongodb-database-plugin \
allowed_roles="my-role" \
connection_url="mongodb://{{username}}:{{password}}@mongodb:27017/admin" \
username="vault" \
password="vault-password"
2. ロールの作成
# MongoDBロール
vault write database/roles/my-role \
db_name=my-mongodb-database \
creation_statements='{ "db": "mydb", "roles": [{ "role": "readWrite" }] }' \
default_ttl="1h" \
max_ttl="24h"
認証情報の使用
アプリケーションでの使用
Python例:
import hvac
import psycopg2
import os
# Vaultクライアントの初期化
client = hvac.Client(
url=os.environ['VAULT_ADDR'],
token=os.environ['VAULT_TOKEN']
)
# 動的な認証情報を取得
creds = client.secrets.database.generate_credentials(name='my-role')
username = creds['data']['username']
password = creds['data']['password']
# データベースに接続
conn = psycopg2.connect(
host='postgres',
database='mydb',
user=username,
password=password
)
# クエリを実行
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()
# 接続を閉じる
cursor.close()
conn.close()
Go例:
package main
import (
"database/sql"
"fmt"
"log"
"os"
vault "github.com/hashicorp/vault/api"
_ "github.com/lib/pq"
)
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"))
// 動的な認証情報を取得
secret, err := client.Logical().Read("database/creds/my-role")
if err != nil {
log.Fatal(err)
}
username := secret.Data["username"].(string)
password := secret.Data["password"].(string)
// データベースに接続
connStr := fmt.Sprintf("host=postgres user=%s password=%s dbname=mydb sslmode=disable",
username, password)
db, err := sql.Open("postgres", connStr)
if err != nil {
log.Fatal(err)
}
defer db.Close()
// クエリを実行
rows, err := db.Query("SELECT * FROM users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
}
リースの管理
リースの更新
# リースを更新
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が使用する管理者パスワードをローテーション
vault write -force database/rotate-root/my-postgresql-database
重要: ローテーション後、古いパスワードは使用できなくなります。
静的ロールのローテーション
# 静的ロールを作成
vault write database/static-roles/my-static-role \
db_name=my-postgresql-database \
username=existing_user \
rotation_period=24h
# パスワードを即座にローテーション
vault write -force database/rotate-role/my-static-role
高度な設定
カスタムSQL文
# カスタム作成文
vault write database/roles/custom-role \
db_name=my-postgresql-database \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT CONNECT ON DATABASE mydb TO \"{{name}}\"; \
GRANT USAGE ON SCHEMA public TO \"{{name}}\"; \
GRANT SELECT, INSERT, UPDATE ON TABLE users TO \"{{name}}\";" \
revocation_statements="REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM \"{{name}}\"; \
DROP ROLE IF EXISTS \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
接続の検証
# 接続をテスト
vault write database/config/my-postgresql-database \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
username="vault" \
password="vault-password" \
verify_connection=true
最大接続数の設定
# 最大接続数を制限
vault write database/config/my-postgresql-database \
plugin_name=postgresql-database-plugin \
connection_url="postgresql://{{username}}:{{password}}@postgres:5432/mydb" \
username="vault" \
password="vault-password" \
max_open_connections=10 \
max_idle_connections=5 \
max_connection_lifetime=1h
ベストプラクティス
1. 短いTTL
# 短いTTLを設定
vault write database/roles/my-role \
db_name=my-postgresql-database \
creation_statements="..." \
default_ttl="30m" \
max_ttl="2h"
2. 最小権限の原則
# 必要最小限の権限のみ付与
vault write database/roles/readonly-role \
db_name=my-postgresql-database \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; \
GRANT SELECT ON TABLE users TO \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
3. 定期的なルート認証情報のローテーション
# 月次でローテーション
vault write -force database/rotate-root/my-postgresql-database
4. 監査ログの確認
# 認証情報の生成を監査
grep "database/creds" /var/log/vault/audit.log
トラブルシューティング
接続エラー
エラー:
Error writing data to database/config/my-postgresql-database: Error making API request.
Code: 400. Errors:
* error verifying connection: dial tcp: lookup postgres: no such host
確認事項:
# 接続URLを確認
vault read database/config/my-postgresql-database
# データベースへの接続を確認
psql -h postgres -U vault -d mydb
権限エラー
エラー:
Error reading database/creds/my-role: Error making API request.
Code: 500. Errors:
* 1 error occurred:
* error creating database object: pq: permission denied to create role
解決策:
-- Vaultユーザーに必要な権限を付与
GRANT CREATE ROLE TO vault;
GRANT CREATE DATABASE TO vault;
ユーザーが削除されない
確認事項:
# 失効文を確認
vault read database/roles/my-role
# 手動で失効
vault lease revoke database/creds/my-role/abc123-def456
次のステップ
データベースシークレットを理解したら、次は動的シークレットで他の動的シークレットの種類を学びましょう。
データベースシークレットの活用データベースシークレットエンジンは、データベースアクセスのセキュリティを大幅に向上させます。短期間の認証情報により、漏洩時の影響を最小化できます。