Cloud Storageバケットでのお客様管理の暗号鍵(CMEK)設定手順について

このブログシリーズ 「クラウドセキュリティ 実践集」 では、一般的なセキュリティ課題を取り上げ、「なぜ危険なのか?」 というリスクの解説から、 「どうやって直すのか?」 という具体的な修復手順(コンソール、Google Cloud CLI、Terraformなど)まで、分かりやすく解説します。
この記事では、Cloud Storageバケットでお客様管理の暗号鍵(CMEK: Customer-Managed Encryption Keys)を設定し、データ暗号化の制御を強化する方法について、具体的な手順とベストプラクティスを解説します。

ポリシーの説明
Google Cloud Storage は既定でGoogle管理の暗号化キー(GMEK)を使用してすべてのデータを暗号化しますが、お客様管理の暗号鍵(CMEK)を使用することで、暗号化キーの制御を完全にお客様側で管理できるようになります。
CMEKを使用することで、データへのアクセスにはCloud Storage のIAM権限に加えて、Cloud KMS の暗号鍵へのアクセス権限も必要となり、二要素認証のような多層防御を実現できます。これにより、より高度なセキュリティ要件やコンプライアンス要件を満たすことが可能になります。
修復方法
コンソールでの修復手順
Google Cloud コンソールを使用して、Cloud Storageバケットに CMEKを設定します。
ステップ1: Cloud KMS APIを有効化
- Google Cloud コンソールにログインし、APIとサービスに移動します
- 検索バーで「Cloud Key Management Service API」を検索します
- 「Cloud Key Management Service (KMS) API」を選択し、「有効にする」をクリックします

ステップ2: 暗号鍵の作成
- Cloud KMSページに移動します
- 「キーリングを作成」をクリックし、以下を設定します:
- キーリング名: 例:
storage-encryption-keys
- ロケーション: バケットと同じリージョンまたはマルチリージョンを選択
- キーリング名: 例:
- 「作成」をクリックします
- 作成したキーリングを選択し、「鍵を作成」をクリックします:
- 鍵名: 例:
gcs-bucket-key
- 保護レベル: 「ソフトウェア」または「HSM」を選択
- 目的: 「対称暗号化/復号化」を選択
- ローテーション期間: セキュリティ要件に応じて設定(推奨:90日)
- 鍵名: 例:
- 「作成」をクリックします
ステップ3: サービスアカウントへの権限付与
- 作成した暗号鍵を選択し、「権限」タブをクリックします
- 「アクセス権を付与」をクリックします
- 新しいプリンシパルに以下のサービスアカウントを追加:
- プリンシパル:
service-[PROJECT_NUMBER]@gs-project-accounts.iam.gserviceaccount.com
- ロール: 「Cloud KMS 暗号鍵の暗号化/復号化」
※ PROJECT_NUMBERは、Google Cloud コンソールの「ダッシュボード」ページ、または以下のコマンドで確認できます:
gcloud projects describe [PROJECT_ID] --format="value(projectNumber)"
- プリンシパル:
- 「保存」をクリックします
ステップ4: 新規バケットの作成(CMEKを有効化)
- Cloud Storageに移動します
- 「バケットを作成」をクリックします
- 基本設定を入力後、「詳細設定」セクションまで進みます
- 「暗号化」セクションで:
- 「顧客管理の暗号鍵」を選択
- 作成した暗号鍵を選択(プロジェクト > キーリング > 鍵)
- 「作成」をクリックしてバケットを作成します
ステップ5: 既存バケットへのCMEK適用
既存のバケットに対してCMEKを適用する場合:
- 対象のバケットを選択し、「設定」タブをクリックします
- 「暗号化」セクションで「編集」をクリックします
- 「顧客管理の暗号鍵」を選択し、作成した鍵を指定します

- 「保存」をクリックします
⚠️ 重要な注意事項: 既存のオブジェクトは自動的に再暗号化されません。CMEKを適用しても、既存のオブジェクトは元の暗号化方式(GMEK)のままです。既存オブジェクトをCMEKで暗号化するには、以下のいずれかの方法が必要です:
gsutil rewrite
コマンドを使用- オブジェクトを再アップロード
Terraformでの修復手順
Cloud StorageバケットでCMEKを有効にするTerraformコードと、主要な修正ポイントを説明します。
# KMSキーリングの作成
resource "google_kms_key_ring" "storage_keyring" {
name = "storage-encryption-keys"
location = var.region # バケットと同じリージョンを指定
project = var.project_id
}
# 暗号化キーの作成
resource "google_kms_crypto_key" "storage_key" {
name = "gcs-bucket-key"
key_ring = google_kms_key_ring.storage_keyring.id
rotation_period = "7776000s" # 90日でローテーション
purpose = "ENCRYPT_DECRYPT"
lifecycle {
prevent_destroy = true # 誤削除防止
}
version_template {
algorithm = "GOOGLE_SYMMETRIC_ENCRYPTION"
protection_level = "SOFTWARE" # または "HSM" for higher security
}
}
# GCSサービスアカウントへのKMS権限付与
data "google_storage_project_service_account" "gcs_account" {
project = var.project_id
}
resource "google_kms_crypto_key_iam_member" "gcs_encrypt_decrypt" {
crypto_key_id = google_kms_crypto_key.storage_key.id
role = "roles/cloudkms.cryptoKeyEncrypterDecrypter"
member = "serviceAccount:${data.google_storage_project_service_account.gcs_account.email_address}"
}
# CMEKを有効化したCloud Storageバケット
resource "google_storage_bucket" "secure_bucket" {
name = "${var.project_id}-secure-data"
location = var.region
project = var.project_id
force_destroy = false
# CMEKの設定
encryption {
default_kms_key_name = google_kms_crypto_key.storage_key.id
}
# 追加のセキュリティ設定
uniform_bucket_level_access = true # 一貫したアクセス制御
versioning {
enabled = true # バージョニングを有効化
}
lifecycle_rule {
condition {
age = 365 # 1年後に削除
}
action {
type = "Delete"
}
}
# 監査ログの設定
logging {
log_bucket = google_storage_bucket.audit_logs.name
log_object_prefix = "gcs-secure-bucket/"
}
depends_on = [
google_kms_crypto_key_iam_member.gcs_encrypt_decrypt
]
}
# 既存オブジェクトの再暗号化(オプション)
resource "null_resource" "reencrypt_objects" {
triggers = {
bucket_name = google_storage_bucket.secure_bucket.name
kms_key = google_kms_crypto_key.storage_key.id
}
provisioner "local-exec" {
command = <<-EOT
# バケット内のすべてのオブジェクトを再暗号化
# -m: マルチスレッドで並列処理(大量のオブジェクトに対して高速化)
# -k: 新しいCMEKキーを指定
# **: すべてのオブジェクトを対象
gsutil -m rewrite -k ${google_kms_crypto_key.storage_key.id} gs://${google_storage_bucket.secure_bucket.name}/**
EOT
}
depends_on = [google_storage_bucket.secure_bucket]
}
# 出力
output "bucket_name" {
description = "作成されたバケット名"
value = google_storage_bucket.secure_bucket.name
}
output "kms_key_id" {
description = "使用されているKMS鍵のID"
value = google_kms_crypto_key.storage_key.id
}
主要な修正ポイント:
- キーリングとバケットの場所を一致: パフォーマンスとコストの最適化
- 適切な権限設定: GCSサービスアカウントにのみ必要最小限の権限を付与
- ローテーション期間の設定: セキュリティ要件に応じて30〜365日で設定
- ライフサイクル保護:
prevent_destroy
で暗号鍵の誤削除を防止 - 依存関係の明示: 権限設定後にバケットを作成するよう
depends_on
を使用
まとめ
この記事では、Cloud Storageバケットでのお客様管理の暗号鍵(CMEK)設定について、リスクと対策を解説しました。
重要なポイント:
- 多層防御の実現: CMEKにより、IAM権限に加えてKMS権限も必要となり、二重の防御層を構築
- コンプライアンス対応: PCI DSS、HIPAA、GDPRなどの規制要件に準拠
- 暗号シュレッディング: 鍵の無効化により即座にデータアクセスを遮断可能
- 包括的な監査: Cloud KMSとCloud Storageの両方で詳細な監査ログを取得
- データ主権の確保: 暗号鍵を自社で完全に管理し、地域要件に対応
CMEKを使用することで、データ暗号化の制御を完全に自社で管理でき、より高度なセキュリティ要件やコンプライアンス要件を満たすことができます。特に以下のような場合は、CMEKの導入を強く推奨します:
- 金融、医療、政府関連のデータを扱う場合
- 個人情報や機密情報を保存する場合
- 厳格なコンプライアンス要件がある場合
- データ主権に関する法的要件がある場合
この問題の検出は弊社が提供するSecurifyのCSPM機能で簡単に検出及び管理する事が可能です。 運用が非常に楽に出来る製品になっていますので、ぜひ興味がある方はお問い合わせお待ちしております。 最後までお読みいただきありがとうございました。この記事が皆さんの役に立てば幸いです。