Secrets Manager・Parameter Store・ACM・CloudHSM
シークレット管理、証明書管理、HSMの詳細設定・使い分け・連携パターンを徹底解説
はじめに:シークレット・証明書管理の全体像
AWSにおけるシークレット・証明書・暗号化キー管理は、セキュリティの根幹をなす機能です。本講では、Secrets Manager、Systems Manager Parameter Store、ACM、CloudHSM の4つのサービスを徹底的に解説します。
各サービスの役割:
- Secrets Manager — データベースパスワード、APIキーなど「変わるシークレット」の自動ローテーション
- Parameter Store — 設定値の暗号化保存、低コスト運用
- ACM — HTTPS証明書の発行・自動更新(AWS内リソース向け)
- CloudHSM — FIPS 140-2準拠の物理HSM、暗号化キーの完全管理
試験ではこれらの 使い分け基準、制約事項、連携パターン が頻出です。
Secrets Manager ローテーションフロー
Loading diagram...
KMS vs CloudHSM 選択判定フロー
Loading diagram...
第1部:AWS Secrets Manager 徹底解説
Secrets Manager の基本概念
Secrets Manager は、シークレット(パスワード、APIキー、認証情報)を安全に保管し、自動ローテーションをサポートするマネージドサービスです。
主な特徴:
- KMSによる自動暗号化
- Lambda関数を使用した自動ローテーション
- クロスアカウント共有(リソースベースのポリシー)
- レプリケーション(複数リージョン対応)
- マルチユーザーシークレット対応
料金体系:
- シークレット保管:1シークレット/月あたり $0.40
- API呼び出し:10,000呼び出しあたり $0.05
- ローテーション:自動ローテーション実行ごとに $0.00(Lambdaのみ課金)
自動ローテーション:詳細メカニズム
Secrets Manager の自動ローテーションは、Lambda関数 を使用してシークレットを定期的に更新します。
ローテーション戦略1:シングルユーザー(Single User)
単一のユーザー・認証情報の場合:
# ローテーションフロー
1. 新しいシークレット値をSecret内に作成
2. Lambda関数が新しいシークレット使用開始(テスト)
3. テスト成功 → Finalize(本番切り替え)
4. 旧シークレットを削除
実装例:RDSパスワードのローテーション
{
"SecretId": "prod/rds/master-password",
"RotationRules": {
"AutomaticallyAfterDays": 30,
"Duration": "3h",
"ScheduleExpression": "rate(30 days)"
},
"RotationLambdaARN": "arn:aws:lambda:us-east-1:123456789012:function:rotate-rds-password",
"RotateImmediatelyOnUpdate": false
}
ローテーション戦略2:交替ユーザー(Alternate User)
複数ユーザーを交互に使い分ける戦略(ダウンタイムなしのローテーション):
# 交替ユーザーフロー
AWSPENDING → 新しいユーザー認証情報を準備
↓
AWSCURRENT → 現在稼働中の認証情報
↓
(ローテーション実行)
↓
AWSPENDING ← 新ユーザー情報で上書き
AWSCURRENT → 旧AWSPENDING(新ユーザー)に切り替え
利点:
- アプリケーションの接続切断がない
- DBスキーマ変更が不要
- 複数ユーザーで即座に切り替え可能
実装例:MySQL 交替ユーザーローテーション Lambda
import boto3
import json
import pymysql
import os
sm_client = boto3.client('secretsmanager')
db = pymysql.connect(
host=os.environ['DB_HOST'],
user=os.environ['DB_USER'],
password=os.environ['DB_PASSWORD']
)
def lambda_handler(event, context):
"""
交替ユーザーでMySQLパスワードをローテーション
"""
secret_id = event['ClientRequestToken']
metadata = sm_client.describe_secret(SecretId=secret_id)
# ステップ判定
if event['Step'] == 'create':
# 新しいユーザーを作成
new_secret = sm_client.get_secret_value(
SecretId=secret_id,
VersionId=secret_id,
VersionStage='AWSPENDING'
)
new_creds = json.loads(new_secret['SecretString'])
with db.cursor() as cursor:
cursor.execute(
f"CREATE USER '{new_creds['username']}'@'%' IDENTIFIED BY '{new_creds['password']}'"
)
cursor.execute(f"GRANT ALL PRIVILEGES ON *.* TO '{new_creds['username']}'@'%'")
db.commit()
elif event['Step'] == 'set':
# 接続テスト
pending_secret = sm_client.get_secret_value(
SecretId=secret_id,
VersionId=secret_id,
VersionStage='AWSPENDING'
)
creds = json.loads(pending_secret['SecretString'])
test_db = pymysql.connect(
host=os.environ['DB_HOST'],
user=creds['username'],
password=creds['password']
)
test_db.close()
elif event['Step'] == 'test':
# テスト済みシークレットの確認
pass
elif event['Step'] == 'finish':
# AWSPENDING → AWSCURRENT(終了)
sm_client.update_secret_version_stage(
SecretId=secret_id,
VersionStage='AWSCURRENT',
MoveToVersionId=event['ClientRequestToken'],
RemoveFromVersionId=metadata['VersionIdsToStages'].get('AWSCURRENT', [''])[0]
)
return {'statusCode': 200}
ローテーション設定の重要なポイント
VPC内データベースの場合の必須設定:
{
"RotationConfiguration": {
"VpcSecurityGroupIds": ["sg-0123456789abcdef0"],
"VpcSubnetIds": [
"subnet-0123456789abcdef0",
"subnet-fedcba9876543210"
]
}
}
Lambda関数がプライベートサブネットのRDSに接続する場合、明示的に VPC設定を指定する必要があります。NAT Gatewayが必要な場合もあります。
ローテーション失敗時の動作:
# ローテーション失敗時の自動リトライ
# → AWS側で自動的に4時間ごとに最大3回リトライ
# → 永続的に失敗する場合はAWS Lambda ロールの権限確認
Secrets Manager のクロスアカウント共有
複数のAWSアカウント間でシークレットを共有する場合、リソースベースのポリシー を設定します。
シナリオ:
- アカウントA(プロダクション)にシークレット保管
- アカウントB、C(開発環境)がそれを読み取り
設定例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"arn:aws:iam::222222222222:role/AppRole-B",
"arn:aws:iam::333333333333:role/AppRole-C"
]
},
"Action": [
"secretsmanager:GetSecretValue",
"secretsmanager:DescribeSecret"
],
"Resource": "*"
}
]
}
CLI実行例:
# クロスアカウント読み取りポリシーをアタッチ
aws secretsmanager put-resource-policy \
--secret-id prod/db/password \
--resource-policy '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::222222222222:root"},
"Action": "secretsmanager:GetSecretValue",
"Resource": "*"
}]
}'
# アカウントBから読み取りテスト
aws secretsmanager get-secret-value \
--secret-id arn:aws:secretsmanager:us-east-1:111111111111:secret:prod/db/password
注意点:
- リソースポリシーは プリンシパルを明示的に指定 する必要がある
"Principal": "*"は使用不可(セキュリティ上の理由)- 読み取り専用権限の付与が推奨
Secrets Manager のレプリケーション
ディザスタリカバリー対応として、シークレットを複数リージョンにレプリケートします。
レプリケーション設定例:
aws secretsmanager replicate-secret-to-regions \
--secret-id prod/api/key \
--add-replica-regions \
Region=us-west-2,KmsKeyId=arn:aws:kms:us-west-2:111111111111:key/xxxxxxxx \
Region=eu-west-1,KmsKeyId=arn:aws:kms:eu-west-1:111111111111:key/yyyyyyyy
レプリケーション時の考慮事項:
- 各リージョンで異なるKMSキーを使用可能
- レプリケーション対象リージョンでのKMS暗号化コスト発生
- ローテーションはプライマリリージョンのみ(自動で全リージョンに反映)
Secrets Manager の制約と「できないこと」
1. シークレットサイズの上限
❌ できないこと:64KB を超えるシークレット保管
✓ 対策:大きなファイル(秘密鍵など)はS3+KMS暗号化を検討
例:2MB の秘密鍵ファイル
# Secrets Manager には不向き
# → S3に保管し、Secrets Managerには S3パスへのアクセスキーを保管
# Secrets Manager内容
{
"s3_bucket": "secure-keys-vault",
"s3_key": "prod/my-secret-key.pem",
"s3_region": "us-east-1"
}
2. Lambda ローテーション関数の VPC要件
ローテーション関数が プライベートサブネット内のリソース(RDS)にアクセス する場合:
❌ Lambda が NAT Gateway なしで外部通信できない
✓ 必須
- VPC内にLambda配置
- Secrets Manager へのアクセス → VPC エンドポイント必須
- NAT Gateway を経由して外部API呼び出し
VPC エンドポイント設定例:
aws ec2 create-vpc-endpoint \
--vpc-id vpc-12345678 \
--service-name com.amazonaws.us-east-1.secretsmanager \
--vpc-endpoint-type Interface \
--subnet-ids subnet-12345678 subnet-87654321
3. ローテーション失敗時の対応不足
自動ローテーションが失敗すると、手動介入が必要になります。
❌ ローテーション失敗時の自動ロールバック機能はない
✓ 対策
- CloudWatch Logs監視
- EventBridge + SNS で失敗通知
- 手動ローテーションプロセスの事前準備
EventBridge 失敗通知設定:
{
"Name": "SecretRotationFailure",
"EventPattern": {
"source": ["aws.secretsmanager"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {
"eventName": ["RotateSecret"],
"errorCode": [{"exists": true}]
}
},
"Targets": [{
"Arn": "arn:aws:sns:us-east-1:111111111111:alert-rotation-failure",
"RoleArn": "arn:aws:iam::111111111111:role/EventBridgeRole"
}]
}
4. リージョン間のローテーション遅延
レプリケート対象リージョンでは、ローテーション反映に 数秒~数分 の遅延が生じます。
❌ 同期的なマルチリージョンローテーション不可
✓ 許容すべき遅延:平均5秒、最大1分程度
試験で狙われるポイント:Secrets Manager
頻出問題パターン:
-
「DBパスワードを自動更新するため、どのサービス組み合わせが最適か?」
- 答え:Secrets Manager + Lambda
- CloudWatch Events でスケジュール設定
- ローテーション失敗通知は EventBridge + SNS
-
「複数リージョンのRDSでパスワード同期が必要。選択肢は?」
- 答え:Secrets Manager のレプリケーション機能
- 各リージョンで異なるKMSキー使用可能
-
「VPC内プライベートDBのパスワードローテーション実装時、Lambda関数が Secrets Manager に接続できない」
- 答え:VPC エンドポイント(com.amazonaws.region.secretsmanager)必須
- Lambda関数にネットワーク権限確認
-
「50MBのSSL秘密鍵をシークレットとして保管したい」
- 答え:不可(64KB上限)
- 代替案:S3 + KMS または CloudHSM
第2部:Parameter Store との比較
Parameter Store の基本概念
Systems Manager Parameter Store は、アプリケーション設定値やシークレットを階層的に保管するサービスです。Secrets Manager と異なり、低コストで小~中規模なパラメータに向く ものです。
比較表:Secrets Manager vs Parameter Store
| 項目 | Secrets Manager | Parameter Store |
|---|---|---|
| 用途 | シークレット自動管理 | 設定値保管 |
| 自動ローテーション | ✓(Lambda利用) | ✗ |
| 暗号化 | KMS自動(必須) | KMS選択可(SecureString) |
| パラメータサイズ | 最大64KB | 最大4KB(Standard)、8KB(Advanced) |
| 階層構造 | ✗ | ✓(/app/db/host) |
| 料金 | $0.40/月/シークレット + API課金 | 無料(Standard)、$0.05/月(Advanced) |
| API呼び出し | 有料 | 無料(GetParameter) |
| スループット | 高(1000 RPS) | 制限あり(Standard:40RPS) |
| クロスアカウント | リソースポリシー | IAMポリシーのみ |
| 監査ログ | CloudTrail(詳細) | CloudTrail(詳細) |
Parameter Store の使い分け基準
Secrets Manager を選ぶ場合:
- DB パスワード、APIキーなど 機密度の高い情報
- 定期的な 自動ローテーション が必要
- 複数アカウント間の共有が必要
Parameter Store を選ぶ場合:
- 環境変数、設定値など 変わりにくい情報
- 低コスト運用が優先
- 階層的な設定管理(
/prod/app/db/host)
Parameter Store:SecureString と KMS
SecureString パラメータは、KMS キーで暗号化されます。
設定例:
# Standard String(暗号化なし)
aws ssm put-parameter \
--name /app/version \
--value "1.2.3" \
--type String
# SecureString(デフォルトKMS)
aws ssm put-parameter \
--name /prod/db/password \
--value "MySecurePassword123!" \
--type SecureString
# SecureString(カスタムKMS キー)
aws ssm put-parameter \
--name /prod/api/key \
--value "sk_prod_xxxxx" \
--type SecureString \
--key-id arn:aws:kms:us-east-1:111111111111:key/12345678-1234-1234-1234-123456789012
読み取り時の暗号化解除:
# WithDecryption=true でKMS復号化を実行
aws ssm get-parameter \
--name /prod/db/password \
--with-decryption
# 出力
{
"Parameter": {
"Name": "/prod/db/password",
"Type": "SecureString",
"Value": "MySecurePassword123!",
"ARN": "arn:aws:ssm:us-east-1:111111111111:parameter/prod/db/password",
"LastModifiedDate": "2026-04-27T10:00:00.000Z"
}
}
Parameter Store:階層とポリシー
Parameters は階層的に整理でき、ポリシーで一括権限付与できます。
階層例:
/prod/
├── app/
│ ├── version: "1.5.2"
│ ├── log_level: "INFO"
│ └── feature_flag_dark_mode: "true"
├── db/
│ ├── host: "prod-db.c9akciq32.us-east-1.rds.amazonaws.com"
│ ├── port: "3306"
│ └── password: "***" (SecureString)
└── cache/
├── redis_host: "prod-redis.xxxxx.ng.0001.use1.cache.amazonaws.com"
└── redis_port: "6379"
/dev/
└── (同じ階層構造)
ポリシーによる一括権限付与:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["ssm:GetParameter", "ssm:GetParameters"],
"Resource": "arn:aws:ssm:*:111111111111:parameter/prod/app/*"
},
{
"Effect": "Allow",
"Action": ["ssm:GetParameter"],
"Resource": "arn:aws:ssm:*:111111111111:parameter/prod/db/password",
"Condition": {
"StringEquals": {
"ssm:resourceTag/Environment": "production"
}
}
}
]
}
Parameter Store の制約
- ❌ 4KB(Standard)/ 8KB(Advanced)を超えるパラメータ不可
- ❌ 自動ローテーション機能なし
- ❌ クロスアカウント共有時は IAMポリシーのみ(リソースポリシーなし)
- ❌ スループット制限(Standard:40 RPS、Advanced:100 RPS)
第3部:AWS Certificate Manager (ACM) 徹底解説
ACM の基本概念と役割
AWS Certificate Manager (ACM) は、X.509 SSL/TLS証明書を無料で発行・管理するサービスです。
主な特徴:
- パブリック証明書(ドメイン検証)
- プライベート証明書(ACM PCA との連携)
- AWS内リソース(ALB、CloudFront、API Gateway)への統合
- 自動更新(有効期限90日前から)
ACM パブリック証明書 vs プライベート証明書
パブリック証明書(AWS CA 発行)
用途:インターネット公開サイト(example.com)
発行元:Amazon CA(Public CA)
信頼チェーン:主要ブラウザで認識
有効期限:発行から1年
自動更新:○(更新条件達成時)
エクスポート:✗(プライベートキーは取得不可)
料金:無料
設定例:
# サブドメインをワイルドカードで含める
aws acm request-certificate \
--domain-name example.com \
--subject-alternative-names \
"example.com" \
"*.example.com" \
"api.example.com" \
--domain-validation-options \
DomainName=example.com,ValidationDomain=example.com \
--region us-east-1
プライベート証明書(ACM PCA 発行)
用途:社内システム、VPN、マイクロサービス間通信
発行元:AWS Certificate Manager Private Certificate Authority
信頼チェーン:社内ルートCAのみ
有効期限:カスタマイズ可(1日~数年)
自動更新:要設定
エクスポート:✓(秘密鍵も含む)
料金:発行ごとに $1.00 + CA月額 $400
ACM PCA + プライベート証明書設定例:
# PCA(ルート認証局)を作成
aws acm-pca create-certificate-authority \
--certificate-authority-configuration \
KeyAlgorithm=RSA_2048,\
SigningAlgorithm=SHA256WITHRSA,\
Subject=\{C=JP,ST=Tokyo,L=Tokyo,O=MyOrg,CN=MyOrgCA\} \
--certificate-authority-type ROOT
# PCA ARN を取得
CA_ARN="arn:aws:acm-pca:us-east-1:111111111111:certificate-authority/12345678-1234-1234-1234-123456789012"
# PCA の証明書発行を有効化
aws acm-pca get-certificate-authority-csr \
--certificate-authority-arn $CA_ARN > ca.csr
# 自己署名ルート証明書を発行
aws acm-pca issue-certificate \
--certificate-authority-arn $CA_ARN \
--csr fileb://ca.csr \
--signing-algorithm SHA256WITHRSA \
--template-arn arn:aws:acm-pca:::template/RootCACertificate/V1
# プライベート証明書を発行
aws acm request-certificate \
--domain-name internal.example.com \
--certificate-authority-arn $CA_ARN \
--region us-east-1
ACM:DNS検証 vs メール検証
証明書の所有者確認は、DNS検証 または メール検証 で行われます。
DNS検証(推奨)
- CloudFlare, Route 53 など DNS自動更新可能
- 自動検証が可能 → 完全自動化
- 検証失敗時:DNS記録が削除されると証明書も無効化
Route 53 での自動検証設定:
# 証明書申請(Route 53自動検証)
aws acm request-certificate \
--domain-name example.com \
--subject-alternative-names '*.example.com' \
--validation-method DNS \
--options CertificateTransparencyLoggingPreference=ENABLED \
--region us-east-1
# 出力:Certificate ARN
# → Route 53 に CNAME レコードが自動作成
必要な IAM権限:
{
"Effect": "Allow",
"Action": [
"route53:GetChange",
"route53:ChangeResourceRecordSets",
"route53:ListResourceRecordSets"
],
"Resource": [
"arn:aws:route53:::hostedzone/Z1234567890ABC",
"arn:aws:route53:::change/*"
]
}
メール検証
- DNS更新が不可能な環境で利用
- メールアドレス:admin@, administrator@, hostmaster@, postmaster@, webmaster@
- 有効期限:メール受信後 72時間以内に承認
- 自動化できない(メール確認を手動実行)
ACM:自動更新の条件
ACM は証明書有効期限 90日前から自動更新 を開始します。
自動更新が成功する条件
- 検証方法が DNS(自動検証が継続)
- ドメイン・SANs に変更なし
- CloudFront、ALB、API Gateway で使用中(実際のリソースで利用されていることを検証)
自動更新が失敗する場合
- メール検証 → 90日ごとにメール承認が必要
- Route 53 へのアクセス権限がない
- ドメイン移管で Route 53 を使用していない
自動更新ステータス確認:
aws acm describe-certificate \
--certificate-arn arn:aws:acm:us-east-1:111111111111:certificate/12345678 \
--region us-east-1
# 出力例
{
"Certificate": {
"DomainName": "example.com",
"ValidationMethod": "DNS",
"RenewalEligibility": "ELIGIBLE",
"RenewalSummary": {
"DomainValidationOptions": [{
"DomainName": "example.com",
"ValidationDomain": "example.com",
"ValidationStatus": "SUCCESS",
"ResourceRecord": {
"Name": "_12345.example.com",
"Type": "CNAME",
"Value": "_67890.acm-validations.aws."
}
}]
}
}
}
ACM の制約と「できないこと」
1. EC2 インスタンスへの直接利用不可
❌ 不可:ACM証明書を EC2 にダウンロード・エクスポート(パブリック証明書の場合)
✓ 対策
- ALB / NLB のターゲットに EC2 を配置
- ACM証明書を ALB にアタッチ
- EC2 上のアプリケーションは HTTP で動作
アーキテクチャ
ユーザー (HTTPS) → ALB (ACM証明書) ← TLS終端 → EC2 (HTTP:8080) ← 非暗号化
2. ACM 証明書のエクスポート(パブリック)不可
❌ 不可:AWS外部で使用するため秘密鍵をエクスポート
✓ 対策
- Nginx/Apache 上で使用する場合 → ACM PCA(プライベート)を使用
- 秘密鍵が必要な場合 → 別途サードパーティCA から購入
3. CloudFront との地域制約
❌ CloudFront で ACM 証明書を使用する場合 → 必ず us-east-1 リージョンで発行・管理
✓ 理由:CloudFront は us-east-1 のみで証明書を読み取り可能
正しい設定例:
# us-east-1 でのみ証明書を発行
aws acm request-certificate \
--domain-name example.com \
--region us-east-1 # ← 必須
# CloudFront ディストリビューション
aws cloudfront create-distribution \
--distribution-config '{
"ViewerProtocolPolicy": "redirect-to-https",
"AcmCertificateArn": "arn:aws:acm:us-east-1:111111111111:certificate/xxxxx"
}'
4. リージョン制約
❌ 別リージョンでは使用不可 例:us-west-1 で発行した証明書を eu-west-1 で使用
✓ 対策:各リージョンで個別に証明書を発行(DNS検証なら自動化可能)
試験で狙われるポイント:ACM
頻出問題:
-
「CloudFront + HTTPSで複数ドメイン対応」
- 答え:ACM(us-east-1で発行)+ SANs(Subject Alternative Names)
-
「社内システム(example.internal)向け証明書」
- 答え:ACM PCA(プライベート証明書)
- コスト:$1.00/発行 + CA月額$400
-
「メールサーバーで ACM 証明書を使いたい」
- 答え:不可(ACM はAWS内リソース向けのみ)
- 代替案:Let’s Encrypt または商用CA
-
「EC2のNginx で HTTPS を終端」
- 答え:ACM では不可(エクスポート不可)
- 代替案:ACM PCA で秘密鍵付き証明書を発行
第4部:AWS CloudHSM 徹底解説
CloudHSM の基本概念
AWS CloudHSM は、FIPS 140-2 Level 3 認証を取得した物理ハードウェアセキュリティモジュール(HSM)をマネージドサービスとして提供します。
主な特徴:
- 専有ハードウェア(自分たちだけで使用)
- キーの完全管理・所有
- AWS 側からキーアクセス不可
- カスタムキーストア経由で KMS と連携可能
KMS vs CloudHSM 比較表
| 項目 | AWS KMS | AWS CloudHSM |
|---|---|---|
| HSM認証 | FIPS 140-2 Level 2 | FIPS 140-2 Level 3 |
| キー所有権 | AWS が管理 | 顧客が完全管理 |
| キーのエクスポート | 不可 | 可能(認証付き) |
| カスタムキーストア | ← CloudHSM と連携可能 | — |
| 自動ローテーション | ○(キーのみ) | ✗(手動管理) |
| マルチテナント | ○ | ✗(専有) |
| 料金 | 従量課金 | $1.46/時間(約$1,050/月) + 初期デプロイ |
| 高可用性 | ○(マルチAZ) | ○(クラスター構成) |
| コンプライアンス | PCI-DSS, HIPAA | PCI-DSS, HIPAA, FedRAMP |
| 運用負荷 | 低 | 高(キー管理、HSM保守) |
CloudHSM:クラスター構成と高可用性
CloudHSM は クラスター として複数HSMを構成し、高可用性を実現します。
推奨構成:
CloudHSM Cluster:
HSM-1 (us-east-1a) ← Primary
├─ 暗号化キー同期
└─ ハートビート
HSM-2 (us-east-1b) ← Replica
HSM-3 (us-east-1c) ← Replica
構成目的:
・1つのHSMが停止 → 他が自動引き継ぎ
・全HSMで同じキー管理
・キー同期遅延:<1秒
CloudHSM クラスター作成例:
# クラスター作成
aws cloudhsm create-cluster \
--hsm-type hsm1.medium \
--region us-east-1
# クラスターARN を取得
CLUSTER_ARN="arn:aws:cloudhsm:us-east-1:111111111111:cluster/cluster-guid"
# HSM を追加(2つ目)
aws cloudhsm create-hsm \
--cluster-id cluster-guid \
--availability-zone us-east-1b
# HSM を追加(3つ目)
aws cloudhsm create-hsm \
--cluster-id cluster-guid \
--availability-zone us-east-1c
# クラスター初期化(最初のHSMのみ)
aws cloudhsm initialize-cluster \
--cluster-id cluster-guid \
--signed-cert "$(cat certificate.pem)"
CloudHSM:カスタムキーストア(KMS統合)
KMS の カスタムキーストア 機能を使用することで、CloudHSM 上のキーで KMS の暗号化を実行できます。
アーキテクチャ:
Application
↓
AWS KMS API (GenerateDataKey, Decrypt)
↓
KMS キー(CloudHSM 上で管理)
↓
CloudHSM クラスター
↓
物理 HSM(FIPS 140-2 Level 3)
カスタムキーストア設定フロー:
# 1. CloudHSM クラスターを構成、HSM初期化
# (上記のクラスター作成参照)
# 2. CloudHSM Java クライアントをインストール
wget https://s3.amazonaws.com/cloudhsmv2-software/CloudHsm/EL7/cloudhsm-client-latest.el7.x86_64.rpm
sudo rpm -ivh cloudhsm-client-latest.el7.x86_64.rpm
# 3. CloudHSM HSM クライアント設定
sudo /opt/cloudhsm/bin/configure -m <HSM_IP>
# 4. CloudHSM にログイン(HCU=Hardware Crypto User)
/opt/cloudhsm/bin/login -m PCO -u admin -p <INITIAL_PASSWORD>
# 5. KMS カスタムキーストアを作成
aws kms create-custom-key-store \
--custom-key-store-name "prod-cloudhsm-keystore" \
--cloud-hsm-cluster-id cluster-guid \
--key-store-password "MySuperSecurePassword123!" \
--region us-east-1
# 6. カスタムキーストアを接続
aws kms connect-custom-key-store \
--custom-key-store-id cks-1234567890abcdef0 \
--region us-east-1
# 7. カスタムキーストア内でKMS キーを作成
aws kms create-key \
--custom-key-store-id cks-1234567890abcdef0 \
--description "Master key in CloudHSM" \
--region us-east-1
# 出力:Key ID
# 以降、このキーは CloudHSM 上で管理される
カスタムキーストア内キーの動作:
# このキーで暗号化すると、CloudHSM が処理
aws kms encrypt \
--key-id arn:aws:kms:us-east-1:111111111111:key/xxxxxxxx \
--plaintext "MySecretData" \
--region us-east-1
# CloudHSM が暗号化処理を実行
# → 物理HSMを離れない(AWSサービスも見えない)
CloudHSM の制約と「できないこと」
1. キーの自動ローテーション不可
❌ 不可:KMS のような自動ローテーション機能(CloudHSM では手動で新キー生成・切り替え)
✓ 対策
- 定期的な手動ローテーションプロセス
- CloudHSM API で新キー生成・古キー削除
- EventBridge + Lambda で手動自動化
手動ローテーション例:
# HSM に接続(CloudHSM Java クライアント)
cd /opt/cloudhsm/bin
# 現在のキーをバックアップ
./key_mgmt.sh key export -i <OLD_KEY_ID> -o old_key.bin
# 新しいキーを生成
./key_mgmt.sh key generate -t RSA -s 2048 -l "prod-key-2026"
# 古キーをディアクティベート(後で削除可能)
./key_mgmt.sh key deactivate -i <OLD_KEY_ID>
# KMS カスタムキーストア内で新キーを有効化
# → アプリケーション再起動 or キーID切り替え
2. 運用負荷が高い
❌ CloudHSM 管理に必要な作業
- HSM OS パッチ(月1回程度)
- キーローテーション(手動)
- HSM ファームウェア更新
- クラスター監視・ヘルスチェック
- 初期化、パスワード管理
✓ 対策
- CloudHSM 運用チームの確保
- 自動化スクリプト・監視ツール開発
- HSM 専門知識の習得
3. クラスター同期の遅延
❌ 全HSMへのキー同期が完了するまで:最大 1秒程度の遅延
✓ 許容
- 分散トランザクション時の一貫性確認
- キー削除後の即座な利用(競合状態)
4. コスト負担が大きい
❌ CloudHSM 専有利用のため:月額 ~$1,050(最小構成) + 初期デプロイ
✓ 採算ラインの検討
- PCI-DSS Level 3 準拠が必須
- 超大規模 SaaS(多テナント暗号化)
- 規制要件が厳しい業界(金融、医療)
CloudHSM のベストプラクティス
1. HA クラスター構成(最低3台)
本番環境:
- 最小 3 HSM(AZ分散)
- クラスター間キー同期
- フェイルオーバー自動化
開発/テスト環境:
- 1~2 HSM でコスト削減
- 本番と異なる構成で学習
2. キーローテーション戦略
# 12ヶ月ごとのローテーションスケジュール
# (前回の講義資料参照)
# ローテーション前:新キー生成 → テスト
# ローテーション日:アプリケーション切り替え
# ローテーション後:旧キー保持(1年)→ 破棄
3. バックアップと災害復旧
# CloudHSM キーのバックアップ(推奨3回/年)
aws cloudhsm create-hsm-backup \
--cluster-id cluster-guid \
--region us-east-1
# バックアップ確認
aws cloudhsm describe-backups \
--region us-east-1
第5部:実践的な連携パターン
パターン1:RDS パスワード自動ローテーション
構成:
- Secrets Manager:RDSパスワード保管
- Lambda:自動ローテーション(30日ごと)
- CloudWatch Events:スケジュール実行
- CloudWatch Logs:監査ログ
実装手順:
# 1. RDS マスターパスワードを Secrets Manager に登録
aws secretsmanager create-secret \
--name prod/rds/master-password \
--secret-string '{"username":"admin","password":"InitialPassword123!"}'
# 2. ローテーション用 Lambda 関数を作成(上述のコード参照)
# 3. Secrets Manager でローテーション設定
aws secretsmanager rotate-secret \
--secret-id prod/rds/master-password \
--rotation-lambda-arn arn:aws:lambda:us-east-1:111111111111:function:rotate-rds-password \
--rotation-rules AutomaticallyAfterDays=30 \
--rotate-immediately
# 4. 監視設定
aws events put-rule \
--name "RDSPasswordRotationFailure" \
--event-pattern '{
"source": ["aws.secretsmanager"],
"detail-type": ["AWS API Call via CloudTrail"],
"detail": {"eventName": ["RotateSecret"], "errorCode": [{"exists": true}]}
}'
パターン2:マルチテナント SaaS の暗号化(CloudHSM + KMS)
要件:
- テナントごとに異なる暗号化キー
- キーは CloudHSM で管理(コンプライアンス)
- KMS API で透過的に利用
実装例:
import boto3
import os
kms_client = boto3.client('kms', region_name='us-east-1')
class TenantCryption:
"""テナントごとの暗号化管理"""
def __init__(self, tenant_id):
self.tenant_id = tenant_id
# カスタムキーストアのキーID(CloudHSM管理)
self.kms_key_id = f"arn:aws:kms:us-east-1:111111111111:key/tenant-{tenant_id}"
def encrypt(self, plaintext):
"""テナントデータを暗号化(CloudHSM で処理)"""
response = kms_client.encrypt(
KeyId=self.kms_key_id,
Plaintext=plaintext
)
return response['CiphertextBlob']
def decrypt(self, ciphertext):
"""テナントデータを復号化(CloudHSM で処理)"""
response = kms_client.decrypt(
CiphertextBlob=ciphertext
)
return response['Plaintext']
# 使用例
for tenant in ['acme-corp', 'widgetco', 'innovatetech']:
crypto = TenantCryption(tenant)
encrypted = crypto.encrypt(b"Sensitive customer data")
print(f"{tenant}: {encrypted[:50]}...")
パターン3:HTTPS + Domain Validation(ACM + Route 53)
完全自動化シナリオ:
# 1. Route 53 でドメインをホスト
# 2. ACM で証明書申請(DNS検証)
# 3. Route 53 に CNAME 自動作成
# 4. 自動検証 → 証明書発行
# 5. 90日後、自動更新開始
# 6. Route 53 CNAME 更新 → 自動検証
# 7. 証明書自動更新完了
# CloudFormation での定義例
Resources:
MySSLCertificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName: example.com
SubjectAlternativeNames:
- '*.example.com'
- 'api.example.com'
ValidationMethod: DNS
DomainValidationOptions:
- DomainName: example.com
ValidationDomain: example.com
MyCloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
ViewerProtocolPolicy: redirect-to-https
AcmCertificateArn: !Ref MySSLCertificate
パターン4:セキュア設定管理(Parameter Store + Secrets Manager 併用)
使い分け原則:
Secrets Manager:
- DB パスワード(機密)
- API キー(機密)
- OAuth トークン(自動ローテーション必須)
Parameter Store:
- アプリバージョン(public)
- ログレベル(public)
- キャッシュTTL(public)
- 内部API端点(SecureString)
実装例:
import boto3
import json
sm = boto3.client('secretsmanager')
ssm = boto3.client('ssm')
class ConfigManager:
"""設定管理の統合インターフェース"""
def get_secret(self, name):
"""Secrets Manager からシークレット取得"""
response = sm.get_secret_value(SecretId=name)
return json.loads(response['SecretString'])
def get_parameter(self, name, decrypt=False):
"""Parameter Store からパラメータ取得"""
response = ssm.get_parameter(
Name=name,
WithDecryption=decrypt
)
return response['Parameter']['Value']
def load_config(self):
"""全設定を一括ロード"""
return {
'db_creds': self.get_secret('prod/db/password'),
'api_key': self.get_secret('prod/external-api/key'),
'app_version': self.get_parameter('/prod/app/version'),
'log_level': self.get_parameter('/prod/app/log_level'),
'internal_api_url': self.get_parameter(
'/prod/internal/api-endpoint',
decrypt=True # SecureString
)
}
# 使用例
config = ConfigManager()
app_config = config.load_config()
# 結果
# {
# 'db_creds': {'username': 'admin', 'password': '...'},
# 'api_key': 'sk_prod_xxxxx',
# 'app_version': '1.5.2',
# 'log_level': 'INFO',
# 'internal_api_url': 'https://api.internal.example.com'
# }
第6部:試験の重要ポイント総括
よく出題される設問パターン
出題1:「パスワード自動ローテーション + クロスアカウント共有」
Q: 本社アカウント(A)のRDSパスワードを子会社アカウント(B)から読み取りたい。
かつ月1回の自動ローテーションが必要。
選択肢:
A) Parameter Store + IAM ポリシー
B) Secrets Manager + リソースポリシー + Lambda ローテーション
C) CloudHSM + KMS カスタムキーストア
D) ACM でプライベート証明書を発行
正解:B
理由:
- 自動ローテーション → Secrets Manager必須
- クロスアカウント → リソースポリシー必須
- Lambda で RDS パスワード変更
出題2:「64MBの秘密鍵の保管」
Q: 64MB の SSL 秘密鍵をシークレットとして管理したい。
選択肢:
A) Secrets Manager(64KB上限に拡張)
B) Parameter Store + S3 ポインタ
C) CloudHSM へ直接格納
D) ACM PCA でエクスポート
正解:B または C
理由:
- Secrets Manager:64KB 上限(変更不可)
- Parameter Store:4~8KB 上限
- CloudHSM:容量制限なし(ただし初期セットアップ必須)
- 実務的解:S3 + KMS + Secrets Manager(ポインタ保管)
出題3:「CloudFront + 自動更新証明書」
Q: CloudFront で複数ドメイン対応し、証明書を自動更新する。
選択肢:
A) ACM(eu-west-1で発行)+ メール検証
B) ACM(us-east-1で発行)+ DNS検証 + Route 53
C) ACM PCA + CloudFront 統合
D) 商用CA(DigiCert 等)
正解:B
理由:
- CloudFront は us-east-1 のみ
- DNS検証で自動化可能
- us-east-1 以外では CloudFront が読み取り不可
出題4:「FIPS 140-2 Level 3 準拠」
Q: FIPS 140-2 Level 3 認証が必須な場合、どのサービスを選ぶ?
選択肢:
A) AWS KMS
B) CloudHSM
C) ACM
D) Secrets Manager
正解:B
理由:
- KMS:Level 2
- CloudHSM:Level 3
- ACM:暗号化キー管理ではなく証明書発行
出題5:「EC2 上の Nginx で HTTPS」
Q: EC2 上の Nginx サーバーで HTTPS を終端したい。
AWS の管理証明書を使用したい。
A) ACM でパブリック証明書を発行しダウンロード
B) ACM PCA でプライベート証明書を発行・ダウンロード
C) CloudHSM の ECC キーをエクスポート
D) Let's Encrypt を使用
正解:B
理由:
- ACM パブリック:エクスポート不可
- ACM PCA:秘密鍵付きで発行可能
- EC2 で秘密鍵が必要 → ACM PCA
結論:ベストプラクティスまとめ
| シナリオ | 最適な組み合わせ | 理由 |
|---|---|---|
| DB パスワード + 自動ローテーション | Secrets Manager + Lambda | 自動ローテーション機能 |
| 小規模な設定値 | Parameter Store | 低コスト |
| マルチアカウント共有(シークレット) | Secrets Manager + リソースポリシー | クロスアカウント対応 |
| CloudFront HTTPS | ACM(us-east-1)+ Route 53 | 自動更新、DNS検証 |
| EC2 HTTPS | ALB + ACM またはACM PCA | エクスポート可能 |
| 規制準拠(FIPS Level 3) | CloudHSM + KMS カスタムキーストア | Level 3 認証 |
| マルチテナント暗号化 | KMS カスタムキーストア(CloudHSM) | テナント分離、所有権確保 |
学習のポイント:
- 各サービスの 用途・制約を明確に区別 する
- 料金体系 を把握(設計判断に影響)
- ローテーション戦略 の違い(シングル vs 交替)
- クロスアカウント 設定(リソースポリシー vs IAMポリシー)
- CloudFront 特殊性(us-east-1 必須)
- CloudHSM は高い (採算ライン判定が重要)
SCS-C03 試験では、これらのサービスを組み合わせた 複合シナリオ が出題されます。 個別の知識だけでなく、全体のアーキテクチャ設計能力 が問われます。