【実務・中級編】 暗号化とKMS統合 – Cloud Spanner

Cloud Spannerの暗号化とKMS統合:データ保護の極限を制するアーキテクチャ設計

こんにちは。テックリードの私だ。
本日は、Cloud Spannerにおける「暗号化とKMS(Key Management Service)統合」について、実務の現場で直面する厳しい要件をクリアするための設計思想と実装パターンを伝授する。

「Google Cloudがデフォルトで暗号化してくれているのだから、CMEK(Customer-Managed Encryption Keys)なんて監査対策の形式的なオプションだろう」――もし、君のチームにそんな甘い認識のエンジニアがいるなら、今すぐこの記事を読ませてほしい。

グローバル規模のトランザクションをさばくCloud Spannerにおいて、鍵のライフサイクル管理と暗号化境界の設計を誤れば、障害時のリカバリ不能、パフォーマンスのデグレ、あるいは致命的なコンプライアンス違反を引き起こす。
単なる公式ドキュメントのなぞりではない、実戦で培った「極限の知見」を共有しよう。

—

1. Cloud Spanner暗号化の基本原理と「デフォルト」の限界

Cloud Spannerは、ストレージに書き込まれるデータ(Data at Rest)、メモリ上のデータ、そしてネットワーク上のデータ(Data in Transit)のすべてにおいて、デフォルトで強力な暗号化(AES-256など)を強制している。これはGoogleがインフラストラクチャレベルで担保しているため、アプリケーション側で特別な設定をせずとも「安全」ではある。

しかし、金融、医療、あるいは厳格な規制を受けるエンタープライズシステムにおいて、「Googleが管理するデフォルト鍵(Google-managed encryption key)」では不十分なケースが多い。

ここで登場するのが CMEK(Customer-Managed Encryption Keys) だ。Cloud KMSを用いて、「暗号鍵の生成、ローテーション、アクセス権限、そして破棄(Revocation)」の主導権を完全に自社の手中に握るための仕組みである。

—

2. CMEK統合のアーキテクチャと「鍵の破棄」という諸刃の剣

CMEKを導入する際、絶対に理解しておかなければならないアーキテクチャ上の特性がある。それは、「SpannerインスタンスとKMS鍵の生死が運命共同体になる」ということだ。

[Cloud Spanner Instance]
↕ (暗号化/復号のたびにリクエスト)
[Cloud KMS (Customer-managed Key)]
↕ (IAMによるアクセス制御)
[Security/Compliance Team]

鍵の無効化・破棄シミュレーション

もし、何らかのセキュリティインシデントやポリシー変更により、Cloud KMS側で鍵の無効化(Disable)や破棄(Destroy)を実行した場合、Cloud Spannerはどうなるか?

  • 即座にデータへのアクセスが遮断される。
  • 既存のコネクションやクエリはエラー(`PERMISSION_DENIED` や `FAILED_PRECONDITION` 相当)を返す。
  • バックアップからのリストアや、ノードのスケールアウト時に鍵へのアクセスが必須となるため、オペレーションが完全に凍結する。

【設計の鉄則】
CMEKを利用する場合、SpannerのIAM権限とKMSのIAM権限は、完全に異なる管理者組織(あるいは厳格に分離されたTerraformリポジトリなど)で管理せよ。単一の管理者が両方を操作できる状態にしておくことは、内部不正や誤操作に対する脆弱性となる。

—

3. 実践:TerraformによるCMEK統合Spannerクラスタの構築

口で言うだけではなく、コードで示そう。以下は、プロダクション環境で耐えうるCMEK統合型Cloud Spannerインスタンスを構築するTerraformの模範解答だ。

1. 鍵リングの作成(リージョンはSpannerインスタンスと同一、またはマルチリージョン)
resource “google_kms_key_ring” “spanner_key_ring” {
name = “prod-spanner-key-ring”
location = “asia-northeast1”
}

2. CMEK用のCrypto Keyの作成(ローテーション設定を必須とする)
resource “google_kms_crypto_key” “spanner_cmek_key” {
name = “prod-spanner-crypto-key”
key_ring = google_kms_key_ring.spanner_key_ring.id
rotation_period = “7776000s” # 90日ごとに自動ローテーション

lifecycle {
prevent_destroy = true # 誤って鍵を削除するのを防ぐ防壁
}
}

3. Cloud Spannerのサービスアカウントへの暗号化/復号権限(KMS CryptoKey Encrypter/Decrypter)の付与
※ Spannerのサービスエージェントは自動生成されるため、プロジェクトのサービスエージェントを指定する
data “google_project” “project” {}

resource “google_kms_crypto_key_iam_member” “spanner_kms_binding” {
crypto_key_id = google_kms_crypto_key.spanner_cmek_key.id
role = “roles/cloudkms.cryptoKeyEncrypterDecrypter”

# Cloud Spannerのサービスエージェントを指定
member = “serviceAccount:service-${data.google_project.project.number}@gcp-sa-spanner.iam.gserviceaccount.com”
}

4. CMEKを適用したCloud Spannerインスタンスの構築
resource “google_spanner_instance” “prod_instance” {
name = “prod-secure-spanner”
config = “regional-asia-northeast1”
display_name = “Production Secure Spanner Instance”
processing_units = 1000

# ここでCMEKを指定する
encryption_config {
kms_key_name = google_kms_crypto_key.spanner_cmek_key.id
}

# 依存関係の明示(IAMバインディングが完了してからインスタンスを作成させる)
depends_on = [
google_kms_crypto_key_iam_member.spanner_kms_binding
]
}

このコードのポイントは `depends_on` だ。IAMの伝播遅延によって「インスタンス作成時に鍵へのアクセス権がない」という初期化エラーを踏まないための、ベテランならではの布石である。

—

4. パフォーマンスとオペレーション上の注意点

「CMEKにすると、クエリのレイテンシが悪化するのではないか?」
これはコードレビューで高頻度で聞かれる質問だ。

結論から言うと、通常のデータ読み書きにおいて、KMSへのラウンドトリップが毎回のクエリごとに発生するわけではない。 Google Cloudのアーキテクチャでは、データ暗号化鍵(DEK: Data Encryption Key)がKMS上の鍵(KEK: Key Encryption Key)でラップされており、キャッシュや内部的な階層構造によってレイテンシのオーバーヘッドは実用上無視できるレベルに最適化されている。

しかし、以下のオペレーションでは明確な違いが出る。

1. インスタンスの起動・復旧時間

  • コールドスタート時や大規模なリストア時には、KMSへのアクセスが発生するため、デフォルト鍵を使用している場合と比較してわずかにプロビジョニング完了までの時間が延びる可能性がある。

2. 鍵のローテーション時の挙動

  • KMS側で鍵がローテーションされても、既存のデータが即座に暗号化し直されるわけではない(Lazy Migration、あるいはバックグラウンドでの再暗号化)。システムを停止させる必要はないが、大規模データセットではバックグラウンドI/Oのリソース消費に注意が必要だ。

—

5. チーフアーキテクトからの総括

暗号化とKMS統合は、単に「セキュリティチェックリストの項目を埋めるための作業」ではない。それは、「万が一のクラウド基盤の侵害や、極端なコンプライアンス要求に対して、自社のデータを物理的・論理的に完全にコントロールし続けるための主権の証明」である。

設計レビューにおいて、次のポイントをクリアしているか確認してほしい。

  • KMSの鍵管理権限とSpannerの運用権限が適切に分離されているか?
  • `prevent_destroy` や鍵の自動ローテーションポリシーがコード化されているか?
  • 障害時(鍵の無効化テストなど)の挙動をステージング環境で検証したか?

これらを網羅したシステムこそが、真に堅牢なグローバル・ミッションクリティカルシステムと呼べる。次のスプリントの設計書に、この知見を直ちに反映させることを期待する。

コメント

タイトルとURLをコピーしました