暗号化されていないSNSトピックの暗号化設定手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、Security Hubで検出された「[SNS.1] SNS トピックは、AWS KMS を使用して保管時に暗号化する必要があります」というセキュリティ課題の修正方法について解説します。

ポリシーの説明
[SNS.1] SNS トピックは、保管時にAWS KMSを使用して暗号化する必要があります
Amazon SNS の Security Hub コントロール – AWS Security Hub
このコントロールは、Amazon SNS トピックが AWS Key Management Service (AWS KMS) に管理されているキーを使用して保管中に暗号化されているかどうかをチェックします。SNS トピックがサーバー側の暗号化 (SSE) に KMS キーを使用しない場合、コントロールは失敗します。デフォルトでは、SNS はディスク暗号化を使用してメッセージとファイルを保存します。このコントロールに合格するには、代わりに暗号化に KMS キーを使用する必要があります。これにより、セキュリティレイヤーが追加され、アクセスコントロールの柔軟性が向上します。
Amazon SNSは、アプリケーションやユーザー間でメッセージを配信するためのスケーラブルなメッセージングサービスです。SNSトピックに保管されるメッセージには、機密情報が含まれる可能性があります。AWS KMS (Key Management Service) を使用して保管時の暗号化を有効にすることで、これらのメッセージは保存時に暗号化され、不正なアクセスから保護されます。
修復方法
AWSコンソールでの修正手順
- Amazon SNS > トピックに移動します
- 「編集」を選択後、暗号化-オプションを有効化します。
- 設定後、必要項目を入力し「トピックの作成」を行う。

Terraformでの修復手順
#-------------------------------
# 変数
#-------------------------------
variable "topic_name" { type = string }
variable "environment" { type = string }
variable "tags" { type = map(string) default = {} }
#-------------------------------
# KMS (カスタム CMK)
#-------------------------------
resource "aws_kms_key" "sns" {
description = "KMS key for SNS encryption"
enable_key_rotation = true
policy = jsonencode({
Version = "2012-10-17",
Statement = [
# ① 口座ルートに全権
{
Sid = "RootAccess",
Effect = "Allow",
Principal= { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" },
Action = "kms:*",
Resource = "*"
},
# ② SNS サービスプリンシパルに最小権限
{
Sid = "AllowSNS",
Effect = "Allow",
Principal= { Service = "sns.amazonaws.com" },
Action = [
"kms:Encrypt","kms:Decrypt",
"kms:GenerateDataKey*","kms:DescribeKey"
],
Resource = "*"
}
]
})
}
resource "aws_kms_alias" "sns" {
name = "alias/sns-${var.environment}"
target_key_id = aws_kms_key.sns.key_id
}
#-------------------------------
# SNS トピック (暗号化あり)
#-------------------------------
resource "aws_sns_topic" "encrypted" {
name = var.topic_name
kms_master_key_id = aws_kms_key.sns.arn
tags = merge(var.tags, {
Environment = var.environment
})
}
output "sns_topic_arn" { value = aws_sns_topic.encrypted.arn }
AWS CLI
REGION="ap-northeast-1"
TOPIC_ARN="arn:aws:sns:${REGION}:123456789012:myTopic"
KEY_ALIAS="alias/sns-encryption-key"
# 1) カスタム CMK 作成
KEY_ID=$(aws kms create-key \\
--description "CMK for SNS encryption" \\
--region $REGION \\
--output text --query 'KeyMetadata.KeyId')
aws kms create-alias \\
--alias-name ${KEY_ALIAS} \\
--target-key-id $KEY_ID \\
--region $REGION
aws kms enable-key-rotation --key-id $KEY_ID --region $REGION
# 2) トピックに割当
aws sns set-topic-attributes \\
--topic-arn $TOPIC_ARN \\
--attribute-name KmsMasterKeyId \\
--attribute-value $KEY_ID \\
--region $REGION
ベストプラクティス & 運用注意点
項目 | 推奨 |
---|---|
キーの種類 | 通常の機密度なら AWS 管理キー (alias/aws/sns ) で SNS.1 は合格。より厳格な管理・クロスアカウント共有が必要なら カスタム CMK を使用。 |
課金 | CMK 使用 10,000 リクエストごとに課金が発生。メッセージ量が多いワークロードではコストを試算してください。AWS ドキュメント |
クロスアカウント配信 | サブスクライバー (SQS / Lambda 他) が別アカウントの場合、そのアカウントにも CMK 参照権限を付与する。 |
継続監査 | AWS Config ルール sns-encrypted-kms を有効化し、逸脱を自動検知。 |
Key policy の最小化 | kms:* ワイルドカードは避け、SNS に必要な 4 アクションのみ許可。 |
最後に
今回は、SNSトピックをAWS KMSを使用して保管時に暗号化する方法についてご紹介しました。SNSトピックに機密性の高いメッセージを扱う場合は、保管時の暗号化を有効にすることで、データのセキュリティを確保することが重要です。カスタマー管理のKMSキー (CMK) を使用することで、より詳細なアクセス制御と監査が可能になります。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。
運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。
最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。