DynamoDB暗号化は後から変えられない──KMSキャッシュ化とデータ移行の話
1人アドベントカレンダー2025 16日目。
DynamoDBの暗号化方式を「後から変えたい」と思ったときに、想定外の壁にぶつかった話です。
前回の記事ではDynamoDB設計の失敗について書きましたが、今回は暗号化まわりの話です。
はじめに
DynamoDB Encryption Clientを使ってクライアントサイド暗号化を実装していた案件で、KMSの呼び出し頻度が想定より高くなり、コスト増が問題になりました。
「KMSの呼び出しをキャッシュすれば解決するのでは?」
そう考えて調査したところ、暗号化方式の変更は設定変更ではなく、データ移行が必要という事実に直面しました。
この記事では、その経緯と学びをまとめます。
構成と前提
今回の構成は以下の通りです。
- DynamoDB Encryption Client(クライアントサイド暗号化)
- DirectKmsMaterialProvider(DKMP) で暗号化マテリアルを取得
- DynamoDBEncryptor + DynamoDBMapper 経由でレコードをread/write
この構成では、暗号化マテリアル取得のために、DynamoDBへのアクセスに応じてKMSが呼び出されます。
暗号化方式の選択肢(整理)
DynamoDB Encryption Clientでは、いくつかの暗号化マテリアルプロバイダ(CMP)を選択できます。
-
DirectKmsMaterialProvider(DKMP)
- レコードの暗号化・復号時にKMSを呼び出す
- 実装はシンプルだが、KMS呼び出し頻度が高くなりやすい
-
CachingMostRecentProvider(CMRP)
- 暗号化マテリアルをキャッシュすることで、KMS呼び出しを抑える
- 既存レコードとの互換性に注意が必要
これらの方式は互換ではなく、導入後に切り替える場合は設定変更ではなく、データ移行が必要になります。
公式ドキュメント:Materials providers
何が起きたか
開発初期は問題なく動作していましたが、本番稼働後にDynamoDBへのアクセス頻度が想定より高くなりました。
DynamoDBのアクセス頻度が上がる = KMSの呼び出し頻度も上がる
結果として、KMSのコストが想定を超えて増加しました。
検討した対策:CachingMostRecentProviderへの切り替え
KMSの呼び出し頻度を下げる方法として、CachingMostRecentProvider(CMRP) への切り替えを検討しました。
CMRPは暗号化マテリアルをキャッシュするため、毎回KMSを呼び出す必要がなくなります。
しかし、ここで問題が発覚しました。
問題:既存レコードにキャッシュ用メタデータがない
DKMPで暗号化されたレコードには、CMRPが必要とするキャッシュ用のメタデータが存在しません。
つまり、CMRPに切り替えると、既存レコードが復号できなくなるのです。
暗号化方式の変更は「設定を変える」だけでは済まず、既存データの移行が必要ということです。
検討した移行方法
移行するとしたら、以下の方法が考えられます。
Lazy Migration(アクセス時に順次移行)
- 任意のレコードに対し、まずCMRPで復号を試みる
- メタデータ欠損などの例外が出た場合、DKMPで復号する
- DKMPで復号した場合、そのレコードをCMRPで再暗号化して保存する
この方法であれば:
- 深夜バッチによる全件移行が不要
- アクセスされるデータだけを順次移行できる
- アクセスされないデータは移行不要(KMS負荷に影響しないため)
この方法の難しさ
一方で、以下の懸念がありました。
- 同時アクセス時の競合更新
- 書き戻しによるレイテンシやWCU増加
- 暗号化まわりを触ること自体のリスク
- 本番稼働中のシステムへの影響
最終的な判断:移行を見送った
結果として、暗号化方式の移行は見送りました。
理由は以下の通りです。
-
内部バグの修正でDynamoDBアクセス頻度が下がった
- アクセス頻度が想定より高かった原因の一部がバグだった
- バグ修正により、KMS呼び出し頻度も許容範囲に収まった
-
移行のコストとリスクが見合わなかった
- 本番稼働中のシステムで暗号化まわりを変更するリスク
- 実装・テスト・リリース調整を含めると軽い対応ではない
「やらない判断」をしたのは、根本原因(バグ)を解消したことで、移行しなくても運用できる状態になったからです。
学び:初期設計で考えるべきこと
今回の経験から学んだことは以下の通りです。
1. 暗号化方式の変更はデータ移行を伴う
「後からキャッシュを有効にすればいい」は通用しません。暗号化方式(CMP)の選択は、初期設計で決める必要がある設計判断です。
2. KMSコストはアクセスパターンに依存する
DynamoDBのアクセス頻度 = KMSの呼び出し頻度になります。想定されるアクセスパターンを元に、KMSコストを見積もっておく必要があります。
3. キャッシュが必要になる可能性を考慮する
将来的にアクセス頻度が増える可能性があるなら、最初からCMRPを採用しておく選択肢もあります。
まとめ
DynamoDB Encryption Clientで暗号化方式を後から変えようとすると、データ移行が必要になります。
- DirectKmsMaterialProvider → CachingMostRecentProvider の切り替えは設定変更ではない
- 既存レコードにはキャッシュ用メタデータがなく、復号できなくなる
- Lazy Migrationで対応可能だが、本番稼働中のシステムではリスクがある
「暗号化方式は後から変えられる」と思わず、初期設計で将来のアクセスパターンを考慮して選択することが重要です。
明日は「DynamoDB begins_withクエリのTips」を書く予定です。
megusunu
🐦 X (@megusunu)
🧶 megusunuLab(ハンドメイド)
🏢 Wells合同会社
Discussion