AWS KMSは「有効にすれば暗号化される」ものの、キーポリシーとIAMの二重統制、リクエスト課金、クロスアカウントの権限設計でつまずきやすいサービスです。CMKとデータキーの関係から実装の落とし穴まで、現場で使う判断軸を整理します。

01KMSは「鍵の階層」で理解する

AWS KMSの設計を誤りやすいのは、いきなりキーポリシーやローテーションから入ってしまうからです。まず押さえるべきは鍵の階層です。KMSでは、あなたが作成・管理する鍵をカスタマーマネージドキー(CMK / customer managed key)と呼びます。CMKの実体は、AWSのHSM(ハードウェアセキュリティモジュール)内にあるHSM backing keyで、平文でHSMの外に出ることは設計上ありません。

この「HSMから出ない鍵」で、実際に大きなデータを直接暗号化するわけではありません。KMSが直接暗号化できるのは最大4KB程度の小さなペイロードに限られます。数百MBのファイルやEBSボリュームを毎回KMSに送って暗号化してもらうのは、レイテンシの面でも課金の面でも現実的ではありません。そこで登場するのがエンベロープ暗号化です。

KMSの鍵には3種類あります。この違いを最初に理解しておくと、コストと統制の議論がぶれません。

現場のコツ:「監査ログ(CloudTrail)で誰がいつ復号したかを追いたいか」「削除・無効化の権限を自分で握りたいか」が、CMKを使うか否かの判断軸です。コンプライアンス要件で鍵の制御証跡が求められるなら迷わずCMK、そうでなければAWSマネージドキーやAWS所有キーで十分なケースは多いです。

02エンベロープ暗号化の仕組み

エンベロープ暗号化は、平文をまずデータキー(DEK / data key)で暗号化し、そのデータキー自体をCMK(KEK / 鍵暗号化鍵)で暗号化する、という二段構えの方式です。実装のフローで理解すると腹落ちします。

アプリケーションは GenerateDataKey をKMSに対して呼び出します。KMSは、平文のデータキーと、それをCMKで暗号化した暗号化データキーの2つを返します。アプリは平文のデータキーでローカルにデータを暗号化し、暗号化が終わったら平文データキーはメモリから破棄します。暗号化データキーは暗号文の隣に一緒に保存しておいて構いません。暗号化されているので、盗まれても復号できないからです。

アプリケーション 暗号化処理 AWS KMS CMK (HSM内) HSMから出ない ストレージ 暗号文 + 暗号化データキー GenerateDataKey 平文キー+暗号化キー ローカルでデータを暗号化 → 平文データキーは破棄 暗号化データキーは暗号文と一緒に保存(復号時にKMSのDecryptで平文キーに戻す)
図:エンベロープ暗号化のフロー。大きなデータはローカルのデータキーで暗号化し、KMSへの通信はデータキーの発行と復号だけに絞る

復号時は逆の流れです。保存しておいた暗号化データキーをKMSの Decrypt に渡すと平文データキーが返り、それでデータを復号します。この方式のおかげで、ネットワークを流れるのは小さなデータキーだけになり、大きなデータはローカルで高速に処理できます。S3やEBS、RDSの暗号化も、内部的にはこのエンベロープ暗号化で動いています。

03キーポリシーとIAMの二重統制

KMSで最も事故が多いのが、権限の考え方です。他のAWSリソースの感覚で「IAMポリシーで kms:Decrypt を許可したのにアクセスできない(またはその逆)」と混乱する人が後を絶ちません。KMSの権限は、キーポリシー・IAMポリシー・グラント(grant)の3つで制御され、しかも評価ルールが独特だからです。

公式ドキュメントの表現が本質を突いています。「キーポリシーが明示的に許可していない限り、IAMポリシーでKMSキーへのアクセスを許可することはできない」。つまり、他リソースなら「IAMで許可すればOK」ですが、KMSではキーポリシー側でIAMへの委任を明示していないと、IAMの許可が一切効かないのです。デフォルトのキーポリシーには、この委任を行う {"AWS": "arn:aws:iam::111122223333:root"} を Principal とするステートメントが含まれており、これがあるからこそアカウント内のIAMポリシーが機能します。

キーポリシー 鍵ごとに1つ root委任があれば IAMを有効化 IAMポリシー プリンシパルに付与 kms:Decrypt など 委任前提で機能 両方が許可 かつ Deny なし アクセス 成立
図:KMSの二重統制。キーポリシーとIAMの両方が許可し、かつ明示的Denyがない場合にのみアクセスが成立する(AND条件)

逆に、明示的なDeny(Deny)はキーポリシーの許可がなくても効きます。ここは他のAWSサービスと同じで、SCPやIAMの Deny はガードレールとして機能します。マルチアカウント統制SCPによるガードレール を敷く際は、この非対称性を利用します。

現場のコツ:設計の初手は「キーポリシーで root 委任を残し、実際のアクセス制御はIAM側に寄せる」パターンが運用しやすいです。鍵の数が増えても、キーポリシーを個別にいじらずIAMで一元管理できるからです。ただし高機密の鍵は、あえてキーポリシーで Principal を絞り、IAM委任を外すことで「IAMを持っていても触れない鍵」を作れます。用途で使い分けてください。IAM最小権限の現実とあわせて設計すると精度が上がります。

04キーローテーションの実務

キーローテーションは「有効にすれば安心」と思われがちですが、何がどう変わるかを正確に理解していないと、監査で説明できず慌てます。KMSの自動ローテーションは、CMKの背後にある鍵素材(HSM backing key)を新しく生成し、以降の暗号化には新しい鍵素材を使う仕組みです。重要なのは、古い鍵素材も保持され続ける点です。過去のデータキーは古い鍵素材で復号できるため、ローテーションしても既存データの再暗号化は不要です。CMKのARNやキーIDも変わりません。

設定のポイントを整理します。数値や上限はバージョン依存のため、必ず公式で最新を確認してください。

コスト面の注意として、自動・オンデマンドを問わず、最初と2回目のローテーションで月額が $1 ずつ加算されます(それぞれ従来の鍵素材を保持するため)。ただし3回目以降のローテーション分は課金されず、加算は2回目で頭打ちになります。つまり長年ローテーションし続けても、1つの鍵の月額が青天井に増えることはありません。

05マルチアカウント・クロスアカウントの設計

エンタープライズでは、鍵を集約管理する専用アカウントに置き、他アカウントのワークロードから使わせる構成が一般的です。ここでの落とし穴は、クロスアカウントアクセスには両側の設定が必要だという点です。片側だけ直しても AccessDenied が消えません。

S3のKMS暗号化バケットをアカウントBのユーザーから使う例で、必要な設定を並べます。

この「キーポリシー+IAM+リソースポリシー」の三点セットが揃って初めて動きます。AWSマネージドキー(aws/s3 など)はキーポリシーを変更できないため、そもそもクロスアカウント共有には使えません。クロスアカウントを見越すなら最初からCMKを選ぶのが鉄則です。

現場のコツ:鍵を集約する専用アカウントを設けると、鍵の棚卸しとローテーション監査が一箇所で済みます。ただしキーポリシーの Principal に個別のロールARNを列挙していくと保守が破綻します。プリンシパルタグとエンコンテキストを使ったABAC(属性ベースアクセス制御)に寄せると、鍵ポリシーを触らずに利用アカウントを増やせます。マルチアカウント全体の設計はOrganizations/SCPガードレールとセットで検討してください。

06コスト設計 — リクエスト課金を侮らない

KMSは「鍵1つ月$1なら安い」と油断すると、リクエスト課金で想定外の請求が来ます。料金は大きく分けて2つです(最新は公式料金ページで確認してください)。

一件あたりは微々たる額ですが、問題はスケールです。たとえばS3で大量の小さいオブジェクトをSSE-KMSで暗号化すると、オブジェクトごとに GenerateDataKey / Decrypt が発生し、リクエスト数が跳ね上がります。高トラフィックなデータレイクでは、KMSリクエスト料金が鍵の保管料を桁違いに上回ることが珍しくありません。

これを劇的に抑えるのが S3バケットキー(S3 Bucket Key)です。バケット単位で短命の鍵をKMSから取得してS3側に一時保持し、その鍵で個々のオブジェクトのデータキーを生成することで、S3からKMSへのリクエストを大幅に削減します。公式によれば、SSE-KMSのKMSリクエストコストを最大99%削減できます。新規バケットではまず有効化を検討すべき機能です。

現場のコツ:S3バケットキーを有効化する際、エンコンテキストが変わる点に注意してください。バケットキー未使用時はオブジェクトARNが、使用時はバケットARNがエンコンテキストになります。IAMポリシーやキーポリシーの kms:EncryptionContext 条件でオブジェクトARNを使っていると、有効化後に権限が効かなくなります。先に条件をバケットARNへ書き換えてください。コスト最適化全般はNAT Gatewayコスト設計のような「地味に効くリクエスト/転送課金」の観点と同じ発想です。

07S3 / EBS / RDS の暗号化を実務で使い分ける

マネージドサービスの暗号化は、内部でエンベロープ暗号化が動くとはいえ、サービスごとに挙動と制約が違います。実務でよく問われるポイントを整理します。

共通する落とし穴は、「後から暗号化」が高コストになる点です。EBSもRDSも、非暗号化で作ってしまうとスナップショット経由の作り直しが必要になり、ダウンタイムやデータ移行の計画が要ります。新規構築時に aws/ebs / aws/rds のAWSマネージドキー、あるいは統制用のCMKでデフォルト暗号化を最初からオンにしておくのが、結果的に一番安く安全です。EBSボリューム選定とあわせて、初期設定段階で暗号化を織り込んでください。

08鍵設計の判断表

最後に、どの鍵タイプを選ぶかの判断軸を表に整理します。迷ったらこの軸で切り分けてください。

実運用では、これらを混在させるのが普通です。機密データのバケットや本番DBはCML、内部ログや一時データはAWSマネージドキー、といった具合に、データの重要度とコストのバランスで割り当てます。全部をCMLにすると鍵の保管料とリクエスト課金、ポリシー保守が膨らむので、「本当に制御が要るデータはどれか」を先に決めるのが設計の勘所です。Secrets Manager/Parameter StoreGuardDuty/Security Hub運用と組み合わせて、暗号化・シークレット・検知を一貫した統制として設計すると、監査対応がぐっと楽になります。

まとめ

KMSの暗号化設計は、次の順で押さえると迷いません。まず鍵の階層(CMK / データキー / エンベロープ暗号化)を理解し、大きなデータはローカルのデータキーで暗号化してKMSへの通信を絞る。次にキーポリシーとIAMの二重統制を理解し、「キーポリシーが委任していないとIAMが効かない」という非対称性を設計に織り込む。ローテーションは既存データの再暗号化不要で、コストも2回目で頭打ち。クロスアカウントは両側の設定が必須でCMK前提。そしてリクエスト課金はスケールで効いてくるため、S3バケットキーのような削減策を最初から検討する。EBS/RDSは「後から暗号化」が高コストなので、新規構築時にデフォルト暗号化をオンにしておく——ここまでを初期設計で決めておけば、KMSはむしろ手のかからない、堅牢な統制基盤になります。

参考(一次情報)

KMSのキー設計やマルチアカウントの暗号化統制でお悩みの際は、お問い合わせください。手を動かすところまで伴走します。

相談する
← ブログ一覧へ戻る