【実務・中級編】 保存時暗号化のメカニズム – Cloud Spanner

Cloud Spannerの暗号化メカニズム:Colossus層の深淵とCMEK運用の実務解

こんにちは。テクニカルリードの私だ。
今日のコードレビュー、あるいはアーキテクチャ設計レビューで、こんな質問を受けたとしよう。

> 「Cloud Spannerって、デフォルトで暗号化されているからセキュリティは万全ですよね? 業務要件でCMEK(顧客管理の暗号鍵)の指定が追加されたんですが、あれってストレージの性能やクエリのレイテンシにどれくらい影響するんですか?あと、鍵をローテーションしたときの挙動がブラックボックスで怖いんですが……」

この問いに、君は自信を持って「こう動くから、設計はこうすべきだ」と即答できるだろうか?
「Googleが勝手にやってくれるので大丈夫です」という回答は、このチームでは一発レッドカードだ。

Cloud Spannerは、グローバル規模のトランザクションと水平スケーリングを両立する怪物級のデータベースだが、その足元(ストレージ層)を支えているのは、Googleの分布式ファイルシステム Colossus だ。今回は、このColossus層における「保存時暗号化(Encryption at Rest)」の物理メカニズムから、CMEKの選定、そして鍵ローテーションがランタイムに及ぼす影響まで、実務で必要となるすべての知見を剥き出しにして解説しよう。

—

1. コアアーキテクチャ:Colossus層におけるデータ暗号化の物理プロセス

まず大前提として、Cloud Spannerのデータは、あなたのアプリケーションが `COMMIT` を叩いた瞬間から、二重・三重の暗号化の網の目にかけられている。

Spannerのコンピュート層(Statelessなクエリ・トランザクション処理ノード)の下位には、ストレージ層である Colossus が存在する。データがこのColossusに永続化されるまでのフローを、レイテンシとセキュリティの観点から分解してみよう。

[Client]
│ (TLS 1.3 / gRPC)
▼
[Spanner Compute Node (Paxos Leader/Follower)]
│ (メモリ上でトランザクション処理 & WAL生成)
│ ※この時点でメモリ上のデータも暗号化対象になり得る
▼
[Colossus Storage Layer]
├── 1. データのチャンク分割とイミュータブル化
├── 2. チャンクごとの暗号化 (DEK: Data Encryption Key)
├── 3. DEKを上位のKEK (Key Encryption Key) でラップ
└── 4. 複数データセンター間への分散・冗長化配置

暗号化の階層構造(Envelope Encryption)

Spannerのストレージ暗号化は、モダンなエンベロープ暗号化(包絡暗号化)の教科書どおりに実装されている。

1. DEK(Data Encryption Key / データ暗号鍵):
実データを暗号化する対称鍵(通常はAES-256)。データブロック単位、あるいはファイル単位で動的に生成される。
2. KEK(Key Encryption Key / 鍵暗号鍵):
DEKを暗号化(ラップ)するための鍵。Google管理、もしくはCMEKの場合はCloud KMSが管理する。
3. 根源の鍵(Root Key / HSM):
KMSの根幹であり、Googleのハードウェアセキュリティモジュール(HSM)の深部に安全に保管されている。

「Colossusに書き込まれる前」の処理

ここで重要なアーキテクチャ上の事実がある。データは、SpannerのコンピュートノードからColossusへ送出される「ネットワーク転送時(In Transit)」にも暗号化されているが、Colossusに到着した「静止時(At Rest)」にも厳格に暗号化されてブロックデバイスレベルで保持される。

パフォーマンス・チューニングの文脈でよくある誤解が、「暗号化/復号化のオーバーヘッドでクエリが遅くなるのではないか」という懸念だ。
結論から言えば、現代のCPU(Intel/AMDのAES-NI命令セットや、Google独自のCustom ASICなど)において、AES-256の暗号化/復号化コストはマイクロ秒オーダーであり、ネットワークの物理遅延やトランザクションのPaxosコンセンサス・プロトコル(複数ノード間のラウンドトリップ)と比較して完全に隠蔽(埋没)されている。レイテンシのボトルネックを暗号化のせいにすることは、大抵の場合、筋違いだ。

—

2. Google管理鍵 vs CMEK:設計の分岐点

プロジェクトのセキュリティ要件定義で必ず議論になるのが、「Google管理の暗号鍵(Default)」を使うべきか、「顧客管理の暗号鍵(CMEK)」を強制すべきか、という点だ。

単なる「コンプライアンス(言われたからCMEK)」ではなく、インフラエンジニアとしてトレードオフを理解した上で設計を選択しよう。

| 評価軸 | Google管理の暗号鍵 (Default) | 顧客管理の暗号鍵 (CMEK via Cloud KMS) |
| :— | :— | :— |
| 運用の複雑性 | ゼロ。Googleがローテーションも可用性も全自動管理。 | 高。KMSのIAM権限、ローテーション方針、障害時の影響範囲を設計・監視する必要がある。 |
| Revoke(失効)の制御 | 不可能(データ削除のみ)。 | 可能。KMS側で鍵のバージョンを無効化(Disabled)することで、インスタンスへのアクセスを即座に遮断できる。 |
| 監査ログの粒度 | Googleの内部監査ログ。 | Cloud Loggingに、誰が・いつ・どの鍵を使ってデータにアクセスしたかの痕跡が完璧に残る。 |
| 可用性リスク | Googleのインフラに依存(ほぼ100%)。 | KMS側の障害や権限ミスにより、Spanner全体がデッドロック・アクセス不能になるリスクが存在。 |

プロジェクト設計のベストプラクティス

金融、ヘルスケア、または厳格なレギュレーションがあるマルチテナントSaaSでない限り、安易なCMEKの導入は「自ら障害の地雷原を増やす行為」になり得る。
もしCMEKを採用する場合、以下の設計ルールをコードレビューで厳守させること。

1. マルチリージョンKMSの原則: Spannerインスタンスがマルチリージョン構成(例: `nam-eur-asia1` 等)である場合、KMSの鍵リングも必ず対応するマルチリージョン、または同一のリージョン配置に合わせる。異なるリージョン間でのKMS呼び出しは、レイテンシの悪化だけでなく、KMS側の障害時にSpanner全体が巻き込まれるリスクを爆発的に高める。
2. Cloud KMSのIAM分離: Spannerの管理者と、Cloud KMSの管理者(CryptoKey Encrypter/Decrypterの付与権限を持つ者)は完全に人権(権限)を分離する。さもなくば、内部不正の防止というCMEKの本質的な目的が崩壊する。

—

3. 暗号鍵のローテーションとデータアクセスの実務的影響

「鍵をローテーションすると、既存のテラバイト級、ペタバイト級のデータはどうなるのか? すべてのデータを再暗号化(Re-encryption)するのか?」

これは実務で必ず聞かれる質問だ。そして、ここがCloud SpannerとColossusの真骨頂が発揮される部分である。

ローテーションの物理:物理的なデータ再暗号化は「即座には」走らない

Cloud KMSやGoogle管理鍵で鍵のローテーション(新しい鍵バージョンの作成)を行ったとき、バックエンドで数TBのデータが裏で一斉にゴリゴリと復号され、新しい鍵で再暗号化される――そんな非効率な処理は走らない。

暗号化の階層構造(Envelope Encryption)を思い出してほしい。
私たちがローテーションするのは、最上位の KEK(Key Encryption Key) である。

1. 新規書き込みデータ: ローテーション後に書き込まれた新しいデータブロックは、新しいKEKバージョンでラップされたDEKによって暗号化される。
2. 既存データ: 過去に書き込まれたデータブロックのDEKをラップしているのは、古いKEKのままである。
3. バックグラウンド・エンベロープ移行: Colossusのガベージコレクションやコンパクション(データの再配置・最適化プロセス)がバックグラウンドで自律的に走るタイミングで、古いブロックは徐々に新しいKEKで再ラップ(Re-wrapped)されていく。

この仕組みにより、ペタバイト級のデータベースであっても、鍵のローテーションは数秒で完了し、データベースのパフォーマンス(IOPS / レイテンシ)には一切影響を与えない。

鍵の失効(Revocation)が引き起こすランタイムの挙動

では、鍵のローテーションではなく、「鍵の無効化(Revocation)」や「Cloud KMSキーの削除」を行った場合はどうなるか?

[KMS Key: Disabled] ──X──> [Spanner Node]
│
▼ (データ復号のためのDEKがラップ解除不能に)
[Query Fail / 503 Service Unavailable]

  • 即座のデータアクセス遮断: 既存データを復号するためのKEKがKMS側で無効化されると、SpannerのコンピュートノードはColossusから読み込んだデータを復号できなくなる。
  • クエリのエラーハンドリング: 該当するパーティションにアクセスする読み取り/書き込みクエリはエラーを返し、アプリケーション層からは `FAILED_PRECONDITION` や `PERMISSION_DENIED`、あるいは一時的な `UNAVAILABLE` として観測される。
  • データは消えていない: これは「データの物理削除(Erasure)」ではなく「鍵の喪失」である。再度KMS側で鍵を有効化(Enable)すれば、数秒〜数分以内にシステムは全快し、データアクセスが復旧する。

—

4. チーフアーキテクトからの設計・運用チェックリスト

最後に、実務の現場において、Cloud Spannerの暗号化周りで事故を起こさないための「実践的チェックリスト」を授けよう。

1. CMEKを使う理由を言語化できているか?

  • 単なる「お上の指示」ではなく、「監査要件」「暗号鍵の即時失効によるフォレンジック対応」など、明確な目的があるか確認したか?

2. KMSキーの削除保護(Deletion Protection)は有効か?

  • Cloud KMSの鍵やキーリングに「削除保護」をかけ忘れて、うっかりテスト環境のつもりで削除し、本番データを闇に葬る悲劇を予防しているか?

3. キーのアクセス監査(Cloud Logging)のアラートは組んであるか?

  • KMSの鍵が誰に、どの頻度で呼び出されているか、異常なアクセス急増やアクセス拒否(Access Denied)が発生した際にPagerDuty等が発報する仕組みはあるか?

4. IAMの循環依存に陥っていないか?

  • Spannerのサービスエージェントに正しく `roles/cloudkms.cryptoKeyEncrypterDecrypter` が付与されているか。Terraform等のIaCで構築する際、依存関係(`depends_on`)の漏れでデプロイがデッドロックしていないか?

—

結びにかえて

Cloud Spannerの保存時暗号化は、単なる「チェックボックスを満たすための機能」ではない。
Colossusという圧倒的な分散ストレージの底知れないスケーラビリティと、Envelope Encryptionという堅牢な暗号数学の美しさが、完璧な調和をもってデザインされた芸術品だ。

このメカニズムの本質を理解していれば、セキュリティ監査官からの意地悪な質問にも、障害時の冷静なトリアージにも、微動だにせず対応できるはずだ。
君たちのプロジェクトが、セキュアかつ最高パフォーマンスで疾走することを期待している。コードレビューに戻るとしよう。

コメント

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