暗号化されていないSSMパラメータの暗号化設定手順

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

この記事では、SSMパラメータストアに登録した文字列が暗号化されていないことによるリスクとその修正方法について解説します。

想定されるリスクについて

リスク詳細
不正アクセスによる情報漏えいIAM 権限の設定ミスやアカウント侵害により、本来アクセスできないユーザー/サービスが平文で機密情報を取得できる。
意図しない公開CLI・CI/CD のログ出力、シェル履歴、アプリケーションの例外スタックなどに平文が残る可能性。
コンプライアンス違反多くの規制で「機密データ at-rest 暗号化」が必須。String 型は at-rest でも暗号化されないため違反リスク。
ローテーション困難SecureString へ移行しておかないと後からタイプを変更できず、大規模な置き換え作業が必要になる。

注: CloudTrail は API 呼び出しのメタデータのみを記録し、パラメータの 値そのもの は残しません。漏えい経路はあくまで IAM 誤設定やログへの平文出力です。

2. 移行方針

  • String → SecureString へ直接変更はできない ➜ 新規 SecureString を作成
  • 値を書き換えるアプリ側も環境変数や設定を更新
  • 旧 String は削除するか “Deprecated” タグを付けて早期廃止

修復方法

パラメータを作成した後に暗号化のタイプを変更することはできないため、新規で作成します。

AWS コンソール

  1. Systems Manager > パラメータストア を開く
  2. パラメータを作成 → 必須項目を入力
  3. タイプ安全な文字列 (SecureString) を選択
  4. KMS キー をカスタムキーまたは aws/ssm から選択
  5. 階層構造/env/app/parameter 形式にし、パラメータを作成

Terraformでの修復手順

SSMパラメータストアのセキュアな設定のためのTerraformコードと、重要な修正ポイントを説明します。

########################################
# KMS  (カスタムキーはローテーション推奨)
########################################
resource "aws_kms_key" "ssm" {
  description             = "KMS key for SSM parameters encryption"
  enable_key_rotation     = true
  deletion_window_in_days = 7

  policy = jsonencode({
    Version   = "2012-10-17",
    Statement = [
      # root に全権
      {
        Sid       = "EnableRoot",
        Effect    = "Allow",
        Principal = { AWS = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:root" },
        Action    = "kms:*",
        Resource  = "*"
      },
      # SSM サービスに最小権限
      {
        Sid       = "AllowSSM",
        Effect    = "Allow",
        Principal = { Service = "ssm.amazonaws.com" },
        Action    = [
          "kms:Encrypt",
          "kms:Decrypt",
          "kms:ReEncrypt*",
          "kms:GenerateDataKey*",
          "kms:DescribeKey"
        ],
        Resource  = "*"
      }
    ]
  })
}

resource "aws_kms_alias" "ssm" {
  name          = "alias/ssm-${var.environment}"
  target_key_id = aws_kms_key.ssm.key_id
}

########################################
# SecureString パラメータ
########################################
resource "aws_ssm_parameter" "secure_parameter" {
  for_each = var.secure_parameters

  name      = "/${var.environment}/${each.key}"   # 階層構造推奨
  type      = "SecureString"
  value     = each.value
  key_id    = aws_kms_key.ssm.arn                # カスタム KMS
  tier      = var.parameter_tier
  overwrite = false                               # 誤更新防止

  tags = merge(var.tags, { Name = each.key })
}

########################################
# IAM (最小権限)
########################################
resource "aws_iam_role" "app" { … }

resource "aws_iam_role_policy" "app_ssm" {
  role   = aws_iam_role.app.id
  policy = jsonencode({
    Version   = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = ["ssm:GetParametersByPath"],
        Resource = "arn:aws:ssm:${data.aws_region.current.name}:${data.aws_caller_identity.current.account_id}:parameter/${var.environment}/*"
      },
      {
        Effect   = "Allow",
        Action   = ["kms:Decrypt"],
        Resource = [aws_kms_key.ssm.arn]
      }
    ]
  })
}

########################################
# 変更監査 – EventBridge + SNS
########################################
resource "aws_cloudwatch_event_rule" "ssm_change" {
  name          = "ssm-parameter-change-${var.environment}"
  event_pattern = jsonencode({
    source       = ["aws.ssm"],
    "detail-type"= ["Parameter Store Change"],
    detail       = { name = [{ "prefix": "/${var.environment}/" }] }
  })
}

resource "aws_cloudwatch_event_target" "notify" {
  rule = aws_cloudwatch_event_rule.ssm_change.name
  arn  = var.alarm_sns_topic_arn
}

ベストプラクティス

項目推奨
命名規則/env/app/component/secret 形式。GetParametersByPath で環境ごとに一括取得。
パラメータポリシーExpiration(有効期限)、NoChangeNotification を活用し、放置や誤変更を検知。
ローテーション要件DB パスワードなど自動ローテーション必須のシークレットは Secrets Manager を検討。
監査・通知EventBridge で変更を SNS / ChatOps に通知。
アクセス権IAM ポリシーはパスプレフィックスで絞り、kms:Decrypt は必要最小限のキー ARN に限定。

最後に

今回は、SSMパラメータストアに登録した文字列が暗号化されていないことによるリスクとその修正方法についてご紹介しました。 パスワードや外部APIのシークレットキーなどの機密データは、パラメータストアの「安全な文字列」として保存しておくことで、安全に管理することができるため実施を推奨します。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。

運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。

最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです

この記事をシェアする

クラウドセキュリティ対策実践集一覧へ戻る

貴社の利用状況に合わせた見積もりを作成します。

料金プランを詳しく見る