## 導入
Cloud Secrets Engine を使用すると、Vault でクラウド プロバイダー (AWS、Azure、GCP) の 動的認証情報 を作成できます。 Vault は、有効期間の長いクラウド認証情報 (IAM アクセス キー、サービス プリンシパル シークレット、サービス アカウント キー) を管理する代わりに、オンデマンドで有効期間の短い認証情報を作成し、TTL の有効期限が切れると自動的に取り消します。
主な利点
- 長期間有効な認証情報は不要: 認証情報が漏洩した場合のリスクを軽減します
- 最小権限: 各リクエストは必要な権限を正確に受け取ります。
- 監査証跡: 誰がいつクラウド認証情報を要求したかを正確に把握します。
- 集中アクセス: 単一の場所からマルチクラウド アクセスを管理
- 自動ローテーション: 手動でキーをローテーションする必要はありません
PHẦN 1: AWS Secrets Engine
###1.1. AWS Secrets Engine のアーキテクチャ
┌──────────────┐ Request AWS creds ┌───────────┐
│ Application │ ─────────────────────▶ │ Vault │
│ │ ◀───────────────────── │ AWS │
│ │ Dynamic IAM creds │ Engine │
└──────────────┘ └─────┬─────┘
│
│ AWS API calls
▼
┌───────────┐
│ AWS │
│ IAM/STS │
└───────────┘
Vault は 3 種類の認証情報をサポートしています。
| タイプ | 説明 | TTL |
|---|---|---|
| IAM ユーザー | IAM ユーザー + アクセスキーを作成 | ロング (キーローテーションあり) |
| STS の役割を引き受ける | AssumeRole → 一時的な認証情報 | 15分~12時間 |
| STS フェデレーション トークン | 取得フェデレーショントークン | 15分~36時間 |
###1.2.有効化と構成
# Enable AWS secrets engine
vault secrets enable aws
# Configure root credentials cho Vault
vault write aws/config/root \
access_key="AKIAIOSFODNN7EXAMPLE" \
secret_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
region="ap-southeast-1"
# Rotate root credentials ngay (khuyến nghị!)
vault write -f aws/config/rotate-root
# Cấu hình lease
vault write aws/config/lease \
lease="30m" \
lease_max="1h"
セキュリティ: ルート認証情報をローテーションした後は、Vault のみが新しいアクセス キーを認識します。回転する前に構成がテストされていることを確認してください。
1.3. IAM User Credentials
アプリケーションがアクセス キーを要求すると、Vault はアクセス キーを持つ IAM ユーザーを作成します。
# Tạo role cho IAM user
vault write aws/roles/s3-readonly \
credential_type=iam_user \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-app-bucket",
"arn:aws:s3:::my-app-bucket/*"
]
}
]
}
EOF
# Hoặc sử dụng existing IAM policy ARN
vault write aws/roles/ec2-admin \
credential_type=iam_user \
policy_arns="arn:aws:iam::aws:policy/AmazonEC2FullAccess"
# Request credentials
vault read aws/creds/s3-readonly
# Output:
# Key Value
# --- -----
# lease_id aws/creds/s3-readonly/abcd1234...
# lease_duration 30m
# lease_renewable true
# access_key AKIAI44QH8DHBEXAMPLE
# secret_key je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
# security_token <nil>
1.4. STS AssumeRole
STS AssumeRole は、IAM ロールを引き受けることによって一時的な認証情報を作成します。IAM ユーザーを作成する必要はありません。
# Tạo IAM role trên AWS trước (Trust policy cho phép Vault assume)
# Trust policy cho Vault's IAM user:
# {
# "Version": "2012-10-17",
# "Statement": [{
# "Effect": "Allow",
# "Principal": {"AWS": "arn:aws:iam::123456789012:user/vault-user"},
# "Action": "sts:AssumeRole"
# }]
# }
# Tạo Vault role cho STS AssumeRole
vault write aws/roles/deploy-role \
credential_type=assumed_role \
role_arns="arn:aws:iam::123456789012:role/DeployRole" \
default_sts_ttl="1h" \
max_sts_ttl="4h"
# Request credentials
vault read aws/creds/deploy-role
# Output:
# Key Value
# --- -----
# lease_id aws/creds/deploy-role/xyz789...
# lease_duration 1h
# lease_renewable false
# access_key ASIAJEXAMPLEXEG2JICEA
# secret_key 9drTJvcXLB89EXAMPLEKEY
# security_token AQoDYXdzEBY... ← STS session token
# STS credentials có security_token — phải sử dụng cả 3 values
export AWS_ACCESS_KEY_ID="ASIAJEXAMPLEXEG2JICEA"
export AWS_SECRET_ACCESS_KEY="9drTJvcXLB89EXAMPLEKEY"
export AWS_SESSION_TOKEN="AQoDYXdzEBY..."
aws s3 ls
1.5. STS Federation Token
# Tạo role Federation Token
vault write aws/roles/ci-deploy \
credential_type=federation_token \
policy_document=-<<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecs:UpdateService",
"ecs:DescribeServices"
],
"Resource": "*"
}
]
}
EOF
# Request credentials
vault read aws/creds/ci-deploy
###1.6.スクリプトは AWS 動的認証情報を使用します
#!/bin/bash
# aws-deploy.sh — Deploy sử dụng Vault dynamic credentials
set -euo pipefail
ROLE="${1:-deploy-role}"
# Lấy credentials từ Vault
echo "Requesting AWS credentials from Vault..."
CREDS=$(vault read -format=json "aws/creds/${ROLE}")
export AWS_ACCESS_KEY_ID=$(echo "$CREDS" | jq -r '.data.access_key')
export AWS_SECRET_ACCESS_KEY=$(echo "$CREDS" | jq -r '.data.secret_key')
# STS credentials có security_token
TOKEN=$(echo "$CREDS" | jq -r '.data.security_token // empty')
if [ -n "$TOKEN" ]; then
export AWS_SESSION_TOKEN="$TOKEN"
fi
LEASE_ID=$(echo "$CREDS" | jq -r '.lease_id')
echo "Got credentials. Lease: $LEASE_ID"
# Cleanup khi exit
cleanup() {
echo "Revoking AWS credentials..."
vault lease revoke "$LEASE_ID" 2>/dev/null || true
}
trap cleanup EXIT
# Thực hiện deploy
echo "Deploying..."
aws ecs update-service \
--cluster production \
--service my-app \
--force-new-deployment
echo "Deploy complete!"
PHẦN 2: Azure Secrets Engine
###2.1.有効化と構成
# Enable Azure secrets engine
vault secrets enable azure
# Configure Azure credentials
vault write azure/config \
subscription_id="aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee" \
tenant_id="11111111-2222-3333-4444-555555555555" \
client_id="66666666-7777-8888-9999-000000000000" \
client_secret="AzureClientSecretValue"
# Rotate root credentials
vault write -f azure/config/rotate-root
2.2. Dynamic Service Principal
Vault は、指定されたロール割り当てを持つ一時的な Azure サービス プリンシパル (SP) を作成します。
# Tạo role — Dynamic SP với Contributor trên Resource Group
vault write azure/roles/contributor-rg \
ttl=1h \
max_ttl=4h \
azure_roles=-<<EOF
[
{
"role_name": "Contributor",
"scope": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/my-app-rg"
}
]
EOF
# Tạo role với nhiều role assignments
vault write azure/roles/devops-role \
ttl=2h \
max_ttl=8h \
azure_roles=-<<EOF
[
{
"role_name": "Contributor",
"scope": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/my-app-rg"
},
{
"role_name": "AcrPush",
"scope": "/subscriptions/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee/resourceGroups/my-app-rg/providers/Microsoft.ContainerRegistry/registries/myappacr"
}
]
EOF
# Request credentials
vault read azure/creds/contributor-rg
# Output:
# Key Value
# --- -----
# client_id zzzzzzzz-yyyy-xxxx-wwww-vvvvvvvvvvvv
# client_secret DynamicGeneratedSecret123!
# lease_duration 1h
# lease_id azure/creds/contributor-rg/abc...
# lease_renewable true
###2.3. Azure の動的資格情報を使用する
# Lấy credentials từ Vault
CREDS=$(vault read -format=json azure/creds/contributor-rg)
CLIENT_ID=$(echo "$CREDS" | jq -r '.data.client_id')
CLIENT_SECRET=$(echo "$CREDS" | jq -r '.data.client_secret')
# Login Azure CLI
az login --service-principal \
--username "$CLIENT_ID" \
--password "$CLIENT_SECRET" \
--tenant "11111111-2222-3333-4444-555555555555"
# Thực hiện operations
az vm list --resource-group my-app-rg
# Cleanup
LEASE_ID=$(echo "$CREDS" | jq -r '.lease_id')
vault lease revoke "$LEASE_ID"
az logout
2.4. Azure Static Roles (Vault 1.21+)
静的ロールを使用すると、Vault で 既存のサービス プリンシパルのパスワード ローテーションを管理できるようになります。
# Tạo static role cho existing SP
vault write azure/static-roles/my-static-sp \
application_object_id="app-object-id-here" \
rotation_period="86400"
# Đọc current credentials
vault read azure/static-creds/my-static-sp
# Output:
# Key Value
# --- -----
# client_id existing-sp-client-id
# client_secret AutoRotatedPassword!
# last_vault_rotation 2024-01-15T12:00:00Z
# rotation_period 24h
# ttl 23h45m
# Force rotation
vault write -f azure/rotate-role/my-static-sp
###2.5。 MS Graph 権限を持つ Azure ロール
# Role với Azure AD permissions (MS Graph)
vault write azure/roles/graph-reader \
ttl=1h \
max_ttl=4h \
azure_groups=-<<EOF
[
{
"group_name": "App-Developers",
"object_id": "group-object-id-here"
}
]
EOF
PHẦN 3: GCP Secrets Engine
###3.1.有効化と構成
# Enable GCP secrets engine
vault secrets enable gcp
# Configure với Service Account key
vault write gcp/config \
credentials=@/path/to/vault-sa-key.json \
ttl=3600 \
max_ttl=86400
3.2. Service Account Key (Roleset)
Vault は一時的なサービス アカウント キーを作成します。
# Tạo roleset cho GCS access
vault write gcp/roleset/gcs-reader \
project="my-gcp-project" \
secret_type="service_account_key" \
bindings=-<<EOF
resource "//cloudresourcemanager.googleapis.com/projects/my-gcp-project" {
roles = [
"roles/storage.objectViewer"
]
}
EOF
# Request Service Account key
vault read gcp/roleset/gcs-reader/key
# Output:
# Key Value
# --- -----
# lease_duration 1h
# lease_id gcp/roleset/gcs-reader/key/abc...
# lease_renewable true
# key_algorithm KEY_ALG_RSA_2048
# key_type TYPE_GOOGLE_CREDENTIALS_FILE
# private_key_data ewogICJ0eXBlIjogInNlcnZpY2VfYWNjb3VudCIsC... ← base64 encoded JSON key
3.3. OAuth2 Access Token (Roleset)
Vault はキーを生成する代わりに、有効期間の短い OAuth2 アクセス トークンを返すことができます。
# Tạo roleset cho OAuth2 tokens
vault write gcp/roleset/compute-viewer \
project="my-gcp-project" \
secret_type="access_token" \
token_scopes="https://www.googleapis.com/auth/compute.readonly" \
bindings=-<<EOF
resource "//cloudresourcemanager.googleapis.com/projects/my-gcp-project" {
roles = [
"roles/compute.viewer"
]
}
EOF
# Request OAuth2 token
vault read gcp/roleset/compute-viewer/token
# Output:
# Key Value
# --- -----
# expires_at_seconds 1705315800
# token ya29.a0AfB_byBq...
# token_ttl 3599
# Sử dụng token
curl -H "Authorization: Bearer ya29.a0AfB_byBq..." \
"https://compute.googleapis.com/compute/v1/projects/my-gcp-project/zones/asia-southeast1-a/instances"
3.4. Static Account
既存のサービス アカウントのキーのローテーションを管理します。
# Tạo static account
vault write gcp/static-account/my-app-sa \
service_account_email="[email protected]" \
secret_type="service_account_key" \
bindings=-<<EOF
resource "//cloudresourcemanager.googleapis.com/projects/my-gcp-project" {
roles = [
"roles/cloudsql.client"
]
}
EOF
# Đọc key
vault read gcp/static-account/my-app-sa/key
# OAuth2 token cho static account
vault write gcp/static-account/my-app-sa \
service_account_email="[email protected]" \
secret_type="access_token" \
token_scopes="https://www.googleapis.com/auth/cloud-platform"
vault read gcp/static-account/my-app-sa/token
# Rotate key
vault write -f gcp/static-account/my-app-sa/rotate-key
###3.5。 GCP 認証情報を使用する
#!/bin/bash
# gcp-deploy.sh — Deploy sử dụng Vault GCP credentials
set -euo pipefail
# Lấy Service Account key từ Vault
KEY_DATA=$(vault read -format=json gcp/roleset/gcs-reader/key | \
jq -r '.data.private_key_data' | base64 -d)
# Ghi ra temp file
KEYFILE=$(mktemp /tmp/gcp-key-XXXXXX.json)
echo "$KEY_DATA" > "$KEYFILE"
# Cleanup khi exit
cleanup() {
rm -f "$KEYFILE"
LEASE_ID=$(vault read -format=json gcp/roleset/gcs-reader/key | jq -r '.lease_id')
vault lease revoke "$LEASE_ID" 2>/dev/null || true
}
trap cleanup EXIT
# Activate Service Account
gcloud auth activate-service-account --key-file="$KEYFILE"
# Thực hiện operations
gsutil ls gs://my-app-bucket/
echo "Done!"
PHẦN 4: Multi-Cloud Best Practices
###4.1.政策組織
# === AWS Policies ===
# Policy cho CI/CD pipeline
path "aws/creds/ci-deploy" {
capabilities = ["read"]
}
# Policy cho developer (read-only)
path "aws/creds/s3-readonly" {
capabilities = ["read"]
}
# === Azure Policies ===
path "azure/creds/contributor-rg" {
capabilities = ["read"]
}
path "azure/static-creds/my-static-sp" {
capabilities = ["read"]
}
# === GCP Policies ===
path "gcp/roleset/gcs-reader/key" {
capabilities = ["read"]
}
path "gcp/roleset/compute-viewer/token" {
capabilities = ["read"]
}
# === Lease Management ===
path "sys/leases/renew" {
capabilities = ["update"]
}
path "sys/leases/revoke" {
capabilities = ["update"]
}
4.2. Multi-Cloud Helper Script
#!/bin/bash
# cloud-creds.sh — Unified script cho multi-cloud credentials
set -euo pipefail
PROVIDER="$1"
ROLE="$2"
shift 2
case "$PROVIDER" in
aws)
echo "Getting AWS credentials..."
CREDS=$(vault read -format=json "aws/creds/${ROLE}")
export AWS_ACCESS_KEY_ID=$(echo "$CREDS" | jq -r '.data.access_key')
export AWS_SECRET_ACCESS_KEY=$(echo "$CREDS" | jq -r '.data.secret_key')
TOKEN=$(echo "$CREDS" | jq -r '.data.security_token // empty')
[ -n "$TOKEN" ] && export AWS_SESSION_TOKEN="$TOKEN"
;;
azure)
echo "Getting Azure credentials..."
CREDS=$(vault read -format=json "azure/creds/${ROLE}")
export AZURE_CLIENT_ID=$(echo "$CREDS" | jq -r '.data.client_id')
export AZURE_CLIENT_SECRET=$(echo "$CREDS" | jq -r '.data.client_secret')
export AZURE_TENANT_ID="your-tenant-id"
;;
gcp)
echo "Getting GCP credentials..."
KEYFILE=$(mktemp /tmp/gcp-key-XXXXXX.json)
vault read -format=json "gcp/roleset/${ROLE}/key" | \
jq -r '.data.private_key_data' | base64 -d > "$KEYFILE"
export GOOGLE_APPLICATION_CREDENTIALS="$KEYFILE"
;;
*)
echo "Unknown provider: $PROVIDER"
echo "Usage: $0 <aws|azure|gcp> <role> -- <command>"
exit 1
;;
esac
# Lưu lease ID cho cleanup
LEASE_ID=$(echo "$CREDS" 2>/dev/null | jq -r '.lease_id // empty')
cleanup() {
[ -n "${LEASE_ID:-}" ] && vault lease revoke "$LEASE_ID" 2>/dev/null || true
[ -n "${KEYFILE:-}" ] && rm -f "$KEYFILE" 2>/dev/null || true
}
trap cleanup EXIT
echo "Credentials ready. Executing command..."
exec "$@"
使用:
# AWS
./cloud-creds.sh aws deploy-role -- aws s3 ls
# Azure
./cloud-creds.sh azure contributor-rg -- az vm list -g my-app-rg
# GCP
./cloud-creds.sh gcp gcs-reader -- gsutil ls gs://my-bucket/
4.3. TTL Guidelines cho Cloud Credentials
| Use Case | AWS | Azure | GCP |
|---|---|---|---|
| CI/CD Pipeline | STS AssumeRole, 30m | Dynamic SP, 1h | OAuth2 Token, 1h |
| Developer Access | STS AssumeRole, 1h | Dynamic SP, 2h | OAuth2 Token, 1h |
| Application Runtime | IAM User + Rotation | Static SP, 24h rotate | Static SA, key rotate |
| Emergency Access | STS AssumeRole, 15m | Dynamic SP, 30m | OAuth2 Token, 30m |
4.4. Monitoring Cloud Credentials
# Kiểm tra active leases cho từng provider
echo "=== AWS Active Leases ==="
vault list sys/leases/lookup/aws/creds/ 2>/dev/null || echo "None"
echo "=== Azure Active Leases ==="
vault list sys/leases/lookup/azure/creds/ 2>/dev/null || echo "None"
echo "=== GCP Active Leases ==="
vault list sys/leases/lookup/gcp/roleset/ 2>/dev/null || echo "None"
# Force revoke tất cả credentials của một provider
# ⚠️ CẨN THẬN — sẽ ảnh hưởng đến applications đang chạy
vault lease revoke -prefix aws/creds
4.5. Security Checklist cho Cloud Engines
AWS:
- ✅ Rotate root credentials ngay sau khi configure
- ✅ IAM ユーザーではなく STS AssumeRole を優先します
- ✅ IAM ポリシーで条件キーを使用する
- ✅ CloudTrail で API 呼び出しを監査できるようにする
- ✅ Least privilege IAM policies cho Vault
Azure:
- ✅ Rotate root credentials ngay sau khi configure
- ✅ スコープのロール割り当ては最小限 (リソース グループ、サブスクリプションなし)
- ✅ 固定 SP を必要とするアプリケーションには Azure 静的ロールを使用します
- ✅ Monitor SP creation trong Azure AD audit logs
GCP:
- ✅ サービス アカウント キーの代わりに OAuth2 アクセス トークンを優先します。
- ✅ Vault SA には
iam.serviceAccountKeyAdminとiam.serviceAccountAdminのみが必要です - ✅ 可能な場合は Workload Identity Federation を使用します
- ✅ Monitor SA key creation trong Cloud Audit Logs
5. Troubleshooting
5.1. AWS Common Issues
# Error: "error assuming role"
# → Kiểm tra trust policy của IAM role
aws iam get-role --role-name DeployRole | jq '.Role.AssumeRolePolicyDocument'
# Error: "AccessDenied"
# → Vault IAM user thiếu permissions
# → Kiểm tra: sts:AssumeRole, iam:CreateUser, iam:CreateAccessKey, etc.
# Error: "cannot use STS token to call IAM"
# → STS credentials không thể tạo IAM users
# → Sử dụng credential_type=assumed_role thay vì iam_user
5.2. Azure Common Issues
# Error: "insufficient privileges"
# → Vault SP cần: Application.ReadWrite.OwnedBy hoặc Application.ReadWrite.All
# → Plus: Role Based Access Control Administrator trên target scope
# Error: "SP not ready"
# → Azure AD replication delay (vài giây đến vài phút)
# → Thêm wait/retry logic trong application
5.3. GCP Common Issues
# Error: "permission denied"
# → Vault SA cần:
# - iam.serviceAccountAdmin
# - iam.serviceAccountKeyAdmin
# - resourcemanager.projectIamAdmin (cho bindings)
# Error: "quota exceeded"
# → GCP giới hạn 10 keys per SA
# → Revoke leases cũ hoặc dùng OAuth2 tokens
## まとめ
このレッスンでは、Cloud Secrets Engine の使用方法をマスターしました。
- AWS Secrets Engine — IAM Users, STS AssumeRole, Federation Tokens
- Azure Secrets Engine — Dynamic Service Principals, Static Roles (1.21+)
- GCP Secrets Engine — Service Account Keys, OAuth2 Tokens, Static Accounts
- Multi-cloud best practices — unified tooling, policies, monitoring
- TTL ガイドライン — ユースケースごとに適切な認証情報の種類と TTL を選択します
- トラブルシューティング — 一般的な問題の処理
これは パート 2: シークレット エンジンの最後の記事です。 KV 静的シークレット、データベースの動的認証情報、PKI 証明書、トランジット暗号化からクラウド認証情報に至るまで、Vault のすべての最も重要なシークレット エンジンの強固な基盤がすでに構築されています。次のセクションでは、認証方法、つまり Vault で ID を認証および管理する方法について詳しく説明します。