Google Cloud SQLで顧客管理暗号化キーの設定について

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

この記事では、Cloud SQLインスタンスでCustomer Managed Encryption Keys (CMEK)による暗号化について、リスクと対策を解説します。

ポリシーの説明

Cloud SQLでは、デフォルトでGoogleが管理する暗号化キー(Google-managed encryption keys)が使用されますが、より高度なセキュリティ要件に対応するため、顧客が管理する暗号化キー(Customer-Managed Encryption Keys: CMEK)を使用することが推奨されます。CMEKを使用することで、暗号化キーのライフサイクル管理、ローテーション、アクセス制御を組織が独自に管理できるようになります。

なぜ危険なのか?

CMEKを使用していないCloud SQLインスタンスには以下のリスクがあります:

  1. 暗号化キーの管理権限不足: Googleが管理するデフォルトの暗号化キーでは、組織独自のコンプライアンス要件や規制要件を満たせない場合があります。
  2. 監査とアクセス制御の制限: CMEKを使用しない場合、暗号化キーへのアクセスログや使用状況の詳細な監査ができません。
  3. データ主権の懸念: 一部の規制では、暗号化キーの完全な制御権を組織が保持することが要求される場合があります。
  4. キーローテーションの柔軟性不足: 組織のセキュリティポリシーに基づいた独自のキーローテーションスケジュールを設定できません。

修復方法

コンソールでの修復手順

Google Cloud コンソールを使用して、Cloud SQLインスタンスでCMEKを有効化します。

  1. Cloud KMS鍵の作成
    • Google Cloud Consoleで「セキュリティ」→「鍵管理」に移動
    • 「鍵リングを作成」をクリックし、以下を設定:
      • 鍵リング名: sql-keyring
      • ロケーション: Cloud SQLインスタンスと同じリージョン
    • 「鍵を作成」をクリックし、以下を設定:
      • 鍵名: sql-cmek-key
      • 保護レベル: ソフトウェア
      • 目的: 対称暗号化/復号化
      • ローテーション期間: 90日(推奨)
  2. Cloud SQLサービスアカウントに権限を付与
    • Cloud SQLインスタンスのサービスアカウントを確認
    • Cloud KMS鍵の「権限」タブで「アクセス権を付与」をクリック
    • プリンシパル: service-[PROJECT_NUMBER]@gcp-sa-cloud-sql.iam.gserviceaccount.com (PROJECT_NUMBERは、Google Cloud Consoleのダッシュボードや「gcloud projects describe PROJECT_ID –format=’value(projectNumber)’」で確認可能)
    • ロール: Cloud KMS CryptoKey 暗号化/復号化
  3. 新しいCloud SQLインスタンスの作成(CMEKを有効化)
    • Cloud SQLコンソールで「インスタンスを作成」をクリック
    • データベースエンジンとバージョンを選択
    • 「設定オプションを表示」をクリック
    • 「セキュリティ」セクションで「暗号化」を展開
    • 「顧客管理の暗号化鍵(CMEK)」を選択
    • 作成したCloud KMS鍵を選択
  4. 既存インスタンスの移行(重要:CMEKは新規作成時のみ設定可能)
    • 既存インスタンスのバックアップを作成
    • CMEKを有効にした新しいインスタンスを作成
    • バックアップから新しいインスタンスにデータを復元
    • アプリケーションの接続先を新しいインスタンスに変更(ダウンタイムが発生します)
    • 接続確認後、古いインスタンスを削除

Terraformでの修復手順

Cloud SQLインスタンスでCMEKを有効にするTerraformコードと、主要な修正ポイントを説明します。

# Cloud KMS鍵リングの作成
resource "google_kms_key_ring" "sql_keyring" {
  name     = "sql-keyring-${var.environment}"
  location = var.region
  project  = var.project_id
}

# Cloud KMS暗号化鍵の作成
resource "google_kms_crypto_key" "sql_key" {
  name            = "sql-cmek-key-${var.environment}"
  key_ring        = google_kms_key_ring.sql_keyring.id
  rotation_period = "7776000s" # 90日(NIST推奨)

  version_template {
    algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION"
  }

  lifecycle {
    prevent_destroy = true
  }
}

# Cloud SQLサービスアカウントの取得
data "google_project" "current" {
  project_id = var.project_id
}

# Cloud KMS鍵へのIAMバインディング
resource "google_kms_crypto_key_iam_binding" "sql_key_binding" {
  crypto_key_id = google_kms_crypto_key.sql_key.id
  role          = "roles/cloudkms.cryptoKeyEncrypterDecrypter"

  members = [
    "serviceAccount:service-${data.google_project.current.number}@gcp-sa-cloud-sql.iam.gserviceaccount.com"
  ]
}

# CMEKを有効にしたCloud SQLインスタンス
resource "google_sql_database_instance" "main" {
  name             = "sql-instance-${var.environment}"
  database_version = "POSTGRES_15"
  region           = var.region

  settings {
    tier              = "db-f1-micro"
    availability_type = "REGIONAL" # 高可用性構成を推奨

    # CMEKの設定
    disk_encryption_configuration {
      kms_key_name = google_kms_crypto_key.sql_key.id
    }

    backup_configuration {
      enabled                        = true
      start_time                     = "03:00"
      location                       = var.region
      point_in_time_recovery_enabled = true
      transaction_log_retention_days = 7

      backup_retention_settings {
        retained_backups = 30
        retention_unit   = "COUNT"
      }
    }

    # メンテナンスウィンドウの設定
    maintenance_window {
      day          = 7  # 日曜日
      hour         = 4  # 4:00 AM
      update_track = "stable"
    }

    ip_configuration {
      ipv4_enabled    = false
      private_network = var.vpc_network_id
      require_ssl     = true
    }
  }

  deletion_protection = true

  depends_on = [
    google_kms_crypto_key_iam_binding.sql_key_binding
  ]
}

# データベースの作成
resource "google_sql_database" "database" {
  name     = var.database_name
  instance = google_sql_database_instance.main.name
}

# データベースユーザーの作成
resource "google_sql_user" "user" {
  name     = var.database_user
  instance = google_sql_database_instance.main.name
  password = var.database_password
}

 

ベストプラクティス

  1. キー管理の分離: Cloud KMS鍵の管理権限とCloud SQL管理権限を異なるチームに分離する
  2. キーローテーション: 90日ごとの自動ローテーションを設定(NIST SP 800-57推奨)
  3. バックアップの暗号化: バックアップも同じCMEKで自動的に暗号化される
  4. 監査ログ: Cloud KMS監査ログを有効化し、鍵の使用状況を監視
  5. リージョン制約: Cloud KMS鍵とCloud SQLインスタンスは同じリージョンに配置する必要がある

注意事項

  • パフォーマンス影響: CMEKによる暗号化・復号化処理により、わずかなレイテンシー増加(通常1-2ms程度)が発生する可能性があります
  • 鍵の削除防止: 誤って鍵を削除するとデータベースにアクセスできなくなるため、prevent_destroyライフサイクルルールを必ず設定
  • コスト: Cloud KMS鍵の使用により追加コストが発生(鍵1つあたり月額$0.06 + 暗号化操作数に応じた料金)

最後に

この記事では、Cloud SQLインスタンスでCustomer Managed Encryption Keys (CMEK)による暗号化について、リスクと対策を解説しました。

CMEKを導入することで、暗号化キーの完全な制御権を獲得し、コンプライアンス要件を満たすことができます。既存インスタンスではCMEKを後から有効化できないため、計画的な移行が必要です。

この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。

参考情報

この記事をシェアする

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

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

料金プランを詳しく見る