KMS キーのパブリックアクセスの修正手順

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、 「どうやって直すのか?」 という具体的な修復手順(コンソール、AWS CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、KMS キーはパブリックにアクセスしないでくださいについて、リスクと対策を解説します。

ポリシーの説明
AWS Key Management Service (KMS) のキーポリシーやIAMポリシーにおいて、KMSキーへのアクセスが信頼されたエンティティのみに制限され、インターネット経由での匿名またはパブリックアクセスが許可されていない状態が最適です。
リスク
KMSキーへのパブリックアクセスが許可されている場合、以下の深刻なセキュリティリスクが発生します:
- 暗号化キーの不正利用: 攻撃者がKMSキーにアクセスできると、暗号化されたデータを復号化したり、新たにデータを暗号化したりすることが可能になります
- 機密データの漏洩: KMSキーで保護されているS3バケット、RDSデータベース、EBSボリュームなどのデータが危険に晒されます
修復方法
コンソールでの修復手順
AWSのコンソールを使用して、KMSキーのパブリックアクセスを無効化します。
- AWSマネジメントコンソールにログインし、KMSサービスに移動します
- 左側のナビゲーションペインから「カスタマー管理型のキー」を選択します
- 対象のKMSキーをクリックして詳細画面を開きます
- 「キーポリシー」タブを選択し、現在のポリシーを確認します

- 「編集」ボタンをクリックして、キーポリシーの編集画面を開きます

- ポリシー内で以下のような危険な設定がないか確認します:
- Principal が “*” になっている
- Principal に “AWS”: “” や “AWS”: “arn:aws:iam:::root” などのワイルドカードが含まれている
- 条件(Condition)なしで外部AWSアカウントへのアクセスを許可している
- StringLike や StringEquals の条件で過度に広範なパターンマッチングを使用している
- 危険な設定を見つけた場合は、Principal を特定のIAMロール、ユーザー、またはAWSアカウントに限定します。例:
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:root"
},
"Action": "kms:*",
"Resource": "*"
}
- 「変更を保存」をクリックしてポリシーを更新します
- IAMポリシーの確認も行います:
- IAMコンソールに移動
- 「ポリシー」を選択し、KMS関連のカスタムポリシーを検索
- 各ポリシーで Resource が特定のKMSキーARNに限定されていることを確認
Terraformでの修復手順
KMSキーのパブリックアクセスを防ぐTerraformコードと、主要な修正ポイントを説明します。
# 安全なKMSキーの設定例
resource "aws_kms_key" "secure_key" {
description = "Secure KMS key with restricted access"
deletion_window_in_days = 30
enable_key_rotation = true
# キーポリシーで特定のAWSアカウントのみにアクセスを限定
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Sid = "Enable IAM User Permissions"
Effect = "Allow"
Principal = {
AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root"
}
Action = "kms:*"
Resource = "*"
},
{
Sid = "Allow use of the key for specific services"
Effect = "Allow"
Principal = {
Service = [
"s3.amazonaws.com",
"rds.amazonaws.com"
]
}
Action = [
"kms:Decrypt",
"kms:GenerateDataKey"
]
Resource = "*"
Condition = {
StringEquals = {
"kms:ViaService" = [
"s3.${data.aws_region.current.name}.amazonaws.com",
"rds.${data.aws_region.current.name}.amazonaws.com"
]
}
}
}
]
})
tags = {
Name = "secure-kms-key"
Environment = "production"
}
}
# KMSキーエイリアス
resource "aws_kms_alias" "secure_key_alias" {
name = "alias/secure-key"
target_key_id = aws_kms_key.secure_key.key_id
}
# 特定のIAMロールにのみKMSキーの使用を許可
resource "aws_iam_role_policy" "kms_user_policy" {
name = "kms-key-user-policy"
role = aws_iam_role.app_role.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"kms:Decrypt",
"kms:GenerateDataKey",
"kms:DescribeKey"
]
Resource = aws_kms_key.secure_key.arn
Condition = {
StringEquals = {
"kms:EncryptionContext:aws:s3:arn" = [
"arn:aws:s3:::my-secure-bucket/*"
]
}
}
}
]
})
}
# データソース
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
主要な修正ポイント:
- Principal の制限: ワイルドカード(*)は使用せず、特定のAWSアカウントやサービスのみを指定
- 条件の追加:
kms:ViaService
条件を使用して、特定のAWSサービス経由のアクセスのみを許可 - 最小権限の原則: 必要最小限のアクションのみを許可(kms:* ではなく、具体的なアクションを指定)
- キーローテーション:
enable_key_rotation = true
で自動キーローテーションを有効化 - 削除保護:
deletion_window_in_days
を設定して、誤削除を防止
最後に
この記事では、KMS キーはパブリックにアクセスしないでくださいについて、リスクと対策を解説しました。
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。