implementing-secrets-management-with-vault
このスキルでは、クラウド環境にHashiCorp Vaultをデプロイして、集中管理型のキー管理を実現できます。データベースやクラウドプロバイダー向けの動的キー生成、転送暗号化(Transit Encryption)、PKI証明書管理、Kubernetes統合など、様々な機能に対応しています。短いライフサイクルと自動ローテーション機能を備えたキーを実装することで、アプリケーションコードとCI/CDパイプラインに埋め込まれた認証情報の問題を解決します。
description の原文を見る
本技能涵盖在云环境中部署 HashiCorp Vault 进行集中式密钥管理,包括为数据库和云提供商生成动态密钥、传输加密(Transit Encryption)、PKI 证书管理以及 Kubernetes 集成。通过实现短生命周期、自动轮换的密钥,解决应用代码和 CI/CD 流水线中硬编码凭据的问题。
SKILL.md 本文
Vault を使用したシークレット管理の実装
適用場面
- アプリケーションがデータベースパスワード、API キー、または証明書を環境変数や設定ファイルに保存している場合
- 静的な長期的認証情報から動的な短期的シークレットへの移行時
- Kubernetes ワークロードがデータベース認証情報またはクラウドプロバイダー API へのセキュアなアクセスを必要とする場合
- コンプライアンス要件により集中管理された認証情報管理と監査ログが必須の場合
- CI/CD パイプラインにサプライチェーン攻撃リスクを代表するハードコードされたシークレットが含まれている場合
非適用: 純粋な AWS 環境(AWS Secrets Manager で十分かつマルチクラウドの必要性がない場合)、アプリケーション層の暗号化ロジック(Vault Transit が補助的に利用可能な場合を除く)、またはアイデンティティフェデレーション場面(managing-cloud-identity-with-okta 参照)。
前提条件
- 高可用(HA)モードでデプロイされた HashiCorp Vault サーバー(Consul または Raft ストレージバックエンド)
- Vault リスニングエンドポイント用の TLS 証明書
- Vault Enterprise ライセンス(ネームスペース、Sentinel ポリシー、および複製用、オプション)
- Vault Agent Injector または CSI プロバイダーが統合された Kubernetes クラスター(ワークロードインテグレーション用)
ワークフロー
ステップ 1: Vault を高可用モードでデプロイ
統合ストレージ(Raft)を使用して Vault をデプロイし、外部の依存性なしで HA を実現します。TLS、監査ログ、およびクラウド KMS ベースの自動アンシール(Auto-Unseal)を設定します。
# vault-config.hcl
storage "raft" {
path = "/opt/vault/data"
node_id = "vault-node-1"
retry_join {
leader_api_addr = "https://vault-node-2.internal:8200"
}
retry_join {
leader_api_addr = "https://vault-node-3.internal:8200"
}
}
listener "tcp" {
address = "0.0.0.0:8200"
tls_cert_file = "/opt/vault/tls/vault.crt"
tls_key_file = "/opt/vault/tls/vault.key"
}
seal "awskms" {
region = "us-east-1"
kms_key_id = "alias/vault-unseal-key"
}
api_addr = "https://vault-node-1.internal:8200"
cluster_addr = "https://vault-node-1.internal:8201"
telemetry {
prometheus_retention_time = "30s"
disable_hostname = true
}
# Vault を初期化
vault operator init -key-shares=5 -key-threshold=3
# 監査ログを有効化
vault audit enable file file_path=/var/log/vault/audit.log
# SIEM 統合用に syslog 監査を有効化
vault audit enable syslog tag="vault" facility="AUTH"
ステップ 2: 認証方法を設定
人間のオペレーター、アプリケーション、および CI/CD パイプライン用の認証バックエンドを有効化します。マシン認証には AppRole、人間アクセスには OIDC を使用します。
# Okta を通じた人間ユーザー向け OIDC 認証を有効化
vault auth enable oidc
vault write auth/oidc/config \
oidc_discovery_url="https://company.okta.com/oauth2/default" \
oidc_client_id="vault-client-id" \
oidc_client_secret="vault-client-secret" \
default_role="default"
# アプリケーション認証用に AppRole を有効化
vault auth enable approle
vault write auth/approle/role/web-app \
secret_id_ttl=10m \
token_num_uses=10 \
token_ttl=20m \
token_max_ttl=30m \
secret_id_num_uses=1 \
token_policies="web-app-policy"
# Pod アクセス用に Kubernetes 認証を有効化
vault auth enable kubernetes
vault write auth/kubernetes/config \
kubernetes_host="https://kubernetes.default.svc:443" \
token_reviewer_jwt=@/var/run/secrets/kubernetes.io/serviceaccount/token \
kubernetes_ca_cert=@/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
ステップ 3: 動的シークレットエンジンを有効化
データベースシークレットエンジンを設定して、オンデマンドで短期的な認証情報を生成します。各認証情報セットに TTL があり、期限切れ後は自動的に失効します。
# PostgreSQL 用データベースシークレットエンジンを有効化
vault secrets enable database
vault write database/config/production-db \
plugin_name=postgresql-database-plugin \
allowed_roles="readonly,readwrite" \
connection_url="postgresql://{{username}}:{{password}}@db.internal:5432/production?sslmode=require" \
username="vault_admin" \
password="initial-password"
# ルート認証情報をローテーション、Vault に独占管理させる
vault write -force database/rotate-root/production-db
# TTL が 1 時間の読み取り専用ロールを作成
vault write database/roles/readonly \
db_name=production-db \
creation_statements="CREATE ROLE \"{{name}}\" WITH LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}'; GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";" \
revocation_statements="REVOKE ALL ON ALL TABLES IN SCHEMA public FROM \"{{name}}\"; DROP ROLE IF EXISTS \"{{name}}\";" \
default_ttl="1h" \
max_ttl="24h"
# AWS シークレットエンジンを有効化して動的 IAM 認証情報を生成
vault secrets enable aws
vault write aws/config/root \
access_key=AKIAEXAMPLE \
secret_key=secretkey \
region=us-east-1
vault write aws/roles/deploy-role \
credential_type=iam_user \
policy_document=@deploy-policy.json \
default_sts_ttl=3600
ステップ 4: Kubernetes ワークロードと統合
Vault Agent Injector または CSI プロバイダーを使用して、アプリケーションコードを変更せずに Pod にシークレットを提供します。シークレットは共有ボリュームにファイルとしてレンダリングされます。
# Vault Agent Injector アノテーション付きの Kubernetes Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
metadata:
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/role: "web-app"
vault.hashicorp.com/agent-inject-secret-db-creds: "database/creds/readonly"
vault.hashicorp.com/agent-inject-template-db-creds: |
{{- with secret "database/creds/readonly" -}}
export DB_USERNAME="{{ .Data.username }}"
export DB_PASSWORD="{{ .Data.password }}"
{{- end }}
spec:
serviceAccountName: web-app
containers:
- name: web-app
image: company/web-app:v2.1
command: ["/bin/sh", "-c", "source /vault/secrets/db-creds && ./start.sh"]
ステップ 5: トランジット暗号化と PKI を実装
Transit シークレットエンジンを使用してアプリケーション層の暗号化サービスを実装し、アプリケーションコード内で暗号化キーを管理する必要をなくします。PKI エンジンをデプロイして TLS 証明書の自動管理を行います。
# Transit エンジンを有効化してサービスとしての暗号化を実現
vault secrets enable transit
vault write -f transit/keys/payment-data type=aes256-gcm96
# 機密データを暗号化
vault write transit/encrypt/payment-data \
plaintext=$(echo "card-number-4111-1111-1111-1111" | base64)
# PKI を有効化して内部証明書管理を行う
vault secrets enable pki
vault secrets tune -max-lease-ttl=87600h pki
# ルート CA を生成
vault write pki/root/generate/internal \
common_name="Internal Root CA" \
ttl=87600h
# 証明書署名用の中間 CA を設定
vault secrets enable -path=pki_int pki
vault write pki_int/intermediate/generate/internal \
common_name="Internal Intermediate CA" \
ttl=43800h
# 証明書発行ロールを作成
vault write pki_int/roles/internal-services \
allowed_domains="internal.company.com" \
allow_subdomains=true \
max_ttl=720h
ステップ 6: ポリシーと監査証跡を確立
最小権限の原則に従ってきめ細かい ACL ポリシーを定義します。すべてのシークレットアクセスと管理操作に対して包括的な監査ログを有効化します。
# web-app-policy.hcl
path "database/creds/readonly" {
capabilities = ["read"]
}
path "transit/encrypt/payment-data" {
capabilities = ["update"]
}
path "transit/decrypt/payment-data" {
capabilities = ["update"]
}
path "secret/data/web-app/*" {
capabilities = ["read", "list"]
}
# 管理パスへのアクセスを禁止
path "sys/*" {
capabilities = ["deny"]
}
# ポリシーを適用
vault policy write web-app-policy web-app-policy.hcl
# すべての操作をキャプチャする監査ログを確認
vault audit list -detailed
コアコンセプト
| 用語 | 定義 |
|---|---|
| 動的シークレット(Dynamic Secrets) | オンデマンドで生成され自動的に期限切れになる認証情報。長期的な静的認証情報を廃止します |
| シークレットエンジン(Secret Engine) | データの保存、生成、または暗号化を行う Vault コンポーネント。KV、database、AWS、PKI、Transit エンジンを含みます |
| 自動アンシール(Auto-Unseal) | クラウド KMS ベースのメカニズム。再起動時に Vault ノードを自動的にアンシールし、手動でのキー入力を不要にします |
| AppRole | マシン向けの認証方法。Role ID と Secret ID を使用してアプリケーションと CI/CD パイプラインへのアクセスをプロビジョニングします |
| Transit エンジン(Transit Engine) | サービスとしての暗号化エンジン。暗号化操作を処理し、アプリケーションに暗号化キーを公開しません |
| リース(Lease) | TTL を持つ期間限定の認証情報。期限切れ後、Vault は自動的に失効させます(更新しない限り) |
| ネームスペース(Namespace) | Vault Enterprise の機能。独立した認証、シークレット、ポリシー管理を備えたテナント分離を提供します |
| レスポンスラッピング(Response Wrapping) | シークレットレスポンスをワンタイムトークンでラップする技術。転送中の中間者攻撃によるシークレット公開を防止します |
ツールと システム
- HashiCorp Vault: コア シークレット管理プラットフォーム。動的シークレット、暗号化、アイデンティティベースのアクセス制御を提供
- Vault Agent Injector: Kubernetes ミューティングウェブフック。サイドカーコンテナを通じて Vault シークレットを Pod ボリュームに自動注入
- Vault CSI Provider: Kubernetes CSI ドライバー。サイドカーコンテナなしで Vault シークレットを Pod ボリュームに直接マウント
- consul-template: テンプレートレンダリング デーモン。Vault シークレットを監視し、シークレット変更時に設定ファイルを再レンダリング
- Vault Radar: シークレット スキャンツール。ソースコード、CI/CD パイプライン、クラウド設定内のハードコード認証情報を検出
一般的なシナリオ
シナリオ: CI/CD パイプラインのハードコードデータベース認証情報を排除
シナリオ背景: DevOps チームが PostgreSQL 認証情報を GitHub Actions シークレットと Jenkins 認証情報ストアに保存しています。同じ認証情報セットがテスト環境と本番環境で使用され、18 カ月間ローテーションされていません。
アプローチ:
- Vault をデプロイし、CI/CD システム向けの AppRole 認証を有効化
- データベースシークレットエンジンを設定。テスト用(readwrite、TTL 2h)と本番用(readonly、TTL 1h)のロールを作成
- 各パイプラインステージ用に独立した Vault ポリシーを作成。対応するデータベースロールへのアクセスを制限
- GitHub Actions ワークフローを更新。各ジョブ開始時に AppRole 経由で認証し、動的認証情報をリクエスト
- 静的 PostgreSQL 認証情報をローテーション。ルートアクセス権を Vault に独占管理させる
- 監査ログを有効化。各認証情報リクエストとパイプラインジョブメタデータを追跡
よくある落とし穴: Vault 移行後、元の静的認証情報をローテーションしないため、古い認証情報が有効なままです。TTL が短すぎて、デプロイ中に実行時間が長いジョブの認証情報が期限切れになります。
出力フォーマット
Vault シークレット管理監査レポート
=======================================
Vault クラスター: vault.internal.company.com
バージョン: 1.18.1 Enterprise
HA モード: Raft (3 ノード)
シール タイプ: AWS KMS 自動アンシール
レポート日時: 2025-02-23
シークレット エンジン:
database/ PostgreSQL 動的認証情報 アクティブ リース: 47
aws/ 動的 IAM 認証情報 アクティブ リース: 12
transit/ サービスとしての暗号化 キー数: 8
pki/ ルート CA 発行済み証明書: 0
pki_int/ 中間 CA 発行済み証明書: 234
secret/ KV v2 静的シークレット バージョン数: 1,892
認証方法:
oidc/ Okta SSO(人間ユーザー) アクティブ トークン: 23
approle/ CI/CD パイプライン アクティブ トークン: 156
kubernetes/ Pod ベース認証 アクティブ トークン: 89
監査結果:
[WARN] 3 個の AppRole の secret_id_num_uses が 0(無制限)に設定
[WARN] 12 個の KV シークレットが 90 日以上アクセスされていない(潜在的孤立シークレット)
[PASS] すべての動的シークレット TTL が 24 時間未満
[PASS] すべてのノードで監査ログが有効化
[PASS] 初期セットアップ後、ルートトークンを失効
認証情報の衛生管理:
静的シークレット (KV): 234
アクティブな動的シークレット: 59
平均リース TTL: 2.3 時間
今月ローテーションされたシークレット: 12,456
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- killvxk
- ライセンス
- Apache-2.0
- 最終更新
- 2026/4/28
Source: https://github.com/killvxk/cybersecurity-skills-zh / ライセンス: Apache-2.0