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種類あります。この違いを最初に理解しておくと、コストと統制の議論がぶれません。
- カスタマーマネージドキー:自分で作り、キーポリシー・ローテーション・削除まで完全に制御できる。月額と使用料が発生する。
- AWSマネージドキー(
aws/s3のようなエイリアス):AWSサービスが自動生成する。ポリシーの変更やローテーション設定は不可。存在自体は無料で、年1回自動ローテーションされる。 - AWS所有キー(AWS owned key):AWSのアカウント側にあり、あなたのアカウントからは監査もできない。完全無料で、2021年以降の新サービスはこれをデフォルトに採用しています。
02エンベロープ暗号化の仕組み
エンベロープ暗号化は、平文をまずデータキー(DEK / data key)で暗号化し、そのデータキー自体をCMK(KEK / 鍵暗号化鍵)で暗号化する、という二段構えの方式です。実装のフローで理解すると腹落ちします。
アプリケーションは GenerateDataKey をKMSに対して呼び出します。KMSは、平文のデータキーと、それをCMKで暗号化した暗号化データキーの2つを返します。アプリは平文のデータキーでローカルにデータを暗号化し、暗号化が終わったら平文データキーはメモリから破棄します。暗号化データキーは暗号文の隣に一緒に保存しておいて構いません。暗号化されているので、盗まれても復号できないからです。
復号時は逆の流れです。保存しておいた暗号化データキーを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ポリシーが機能します。
逆に、明示的なDeny(Deny)はキーポリシーの許可がなくても効きます。ここは他のAWSサービスと同じで、SCPやIAMの Deny はガードレールとして機能します。マルチアカウント統制で SCPによるガードレール を敷く際は、この非対称性を利用します。
root 委任を残し、実際のアクセス制御はIAM側に寄せる」パターンが運用しやすいです。鍵の数が増えても、キーポリシーを個別にいじらずIAMで一元管理できるからです。ただし高機密の鍵は、あえてキーポリシーで Principal を絞り、IAM委任を外すことで「IAMを持っていても触れない鍵」を作れます。用途で使い分けてください。IAM最小権限の現実とあわせて設計すると精度が上がります。04キーローテーションの実務
キーローテーションは「有効にすれば安心」と思われがちですが、何がどう変わるかを正確に理解していないと、監査で説明できず慌てます。KMSの自動ローテーションは、CMKの背後にある鍵素材(HSM backing key)を新しく生成し、以降の暗号化には新しい鍵素材を使う仕組みです。重要なのは、古い鍵素材も保持され続ける点です。過去のデータキーは古い鍵素材で復号できるため、ローテーションしても既存データの再暗号化は不要です。CMKのARNやキーIDも変わりません。
設定のポイントを整理します。数値や上限はバージョン依存のため、必ず公式で最新を確認してください。
- 自動ローテーション:デフォルトで約1年ごと。カスタムのローテーション周期(日数)も指定できます。対称暗号化KMSキーのみ対応。
- オンデマンドローテーション:
RotateKeyOnDemandで即座にローテーション可能。自動ローテーションの有無に関わらず実行でき、既存の自動スケジュールには影響しません。鍵1つあたりの回数上限があります(公式で最新を確認)。 - 非対称・HMAC・カスタムキーストア:自動・オンデマンドともローテーション非対応。これらは手動で新しい鍵を作り、エイリアスを付け替える運用になります。
コスト面の注意として、自動・オンデマンドを問わず、最初と2回目のローテーションで月額が $1 ずつ加算されます(それぞれ従来の鍵素材を保持するため)。ただし3回目以降のローテーション分は課金されず、加算は2回目で頭打ちになります。つまり長年ローテーションし続けても、1つの鍵の月額が青天井に増えることはありません。
05マルチアカウント・クロスアカウントの設計
エンタープライズでは、鍵を集約管理する専用アカウントに置き、他アカウントのワークロードから使わせる構成が一般的です。ここでの落とし穴は、クロスアカウントアクセスには両側の設定が必要だという点です。片側だけ直しても AccessDenied が消えません。
S3のKMS暗号化バケットをアカウントBのユーザーから使う例で、必要な設定を並べます。
- アカウントA(鍵側):CMKのキーポリシーで、アカウントB(またはそのプリンシパル)に
kms:Decrypt/kms:GenerateDataKeyなどを許可する。 - アカウントB(利用側):IAMポリシーで、アカウントAのバケットとCMKの両方へのアクセスを許可する。
- S3側:バケットポリシーでアカウントBを許可する。
この「キーポリシー+IAM+リソースポリシー」の三点セットが揃って初めて動きます。AWSマネージドキー(aws/s3 など)はキーポリシーを変更できないため、そもそもクロスアカウント共有には使えません。クロスアカウントを見越すなら最初からCMKを選ぶのが鉄則です。
Principal に個別のロールARNを列挙していくと保守が破綻します。プリンシパルタグとエンコンテキストを使ったABAC(属性ベースアクセス制御)に寄せると、鍵ポリシーを触らずに利用アカウントを増やせます。マルチアカウント全体の設計はOrganizations/SCPガードレールとセットで検討してください。06コスト設計 — リクエスト課金を侮らない
KMSは「鍵1つ月$1なら安い」と油断すると、リクエスト課金で想定外の請求が来ます。料金は大きく分けて2つです(最新は公式料金ページで確認してください)。
- 鍵の保管料:CMK 1つあたり月 $1(時間割)。無料枠の対象外で、作成した瞬間から発生します。
- リクエスト課金:対称鍵の
Encrypt/Decrypt/GenerateDataKeyは 10,000リクエストあたり $0.03。月20,000リクエストの無料枠あり。
一件あたりは微々たる額ですが、問題はスケールです。たとえばS3で大量の小さいオブジェクトをSSE-KMSで暗号化すると、オブジェクトごとに GenerateDataKey / Decrypt が発生し、リクエスト数が跳ね上がります。高トラフィックなデータレイクでは、KMSリクエスト料金が鍵の保管料を桁違いに上回ることが珍しくありません。
これを劇的に抑えるのが S3バケットキー(S3 Bucket Key)です。バケット単位で短命の鍵をKMSから取得してS3側に一時保持し、その鍵で個々のオブジェクトのデータキーを生成することで、S3からKMSへのリクエストを大幅に削減します。公式によれば、SSE-KMSのKMSリクエストコストを最大99%削減できます。新規バケットではまず有効化を検討すべき機能です。
kms:EncryptionContext 条件でオブジェクトARNを使っていると、有効化後に権限が効かなくなります。先に条件をバケットARNへ書き換えてください。コスト最適化全般はNAT Gatewayコスト設計のような「地味に効くリクエスト/転送課金」の観点と同じ発想です。07S3 / EBS / RDS の暗号化を実務で使い分ける
マネージドサービスの暗号化は、内部でエンベロープ暗号化が動くとはいえ、サービスごとに挙動と制約が違います。実務でよく問われるポイントを整理します。
- S3(SSE-KMS):オブジェクト単位でデータキーを生成。リクエスト課金が効いてくるのでバケットキーの有効化が定石。クロスアカウント共有はCMK必須。
- EBS:ボリューム作成時にCMKを指定。暗号化されていないボリュームを後から直接暗号化に変えられないため、スナップショット経由でコピーして暗号化する手順が必要です。アカウント単位でEBSのデフォルト暗号化を有効にしておくと、暗号化漏れを防げます。
- RDS / Aurora:暗号化の有効/無効はDB作成時にしか決められません。既存の非暗号化DBを暗号化するには、スナップショットを暗号化コピーして復元する必要があります。リードレプリカは基本的に元のDBと同じ暗号化状態を引き継ぎます。Aurora/RDS選定の段階で暗号化方針を固めておくのが安全です。
共通する落とし穴は、「後から暗号化」が高コストになる点です。EBSもRDSも、非暗号化で作ってしまうとスナップショット経由の作り直しが必要になり、ダウンタイムやデータ移行の計画が要ります。新規構築時に aws/ebs / aws/rds のAWSマネージドキー、あるいは統制用のCMKでデフォルト暗号化を最初からオンにしておくのが、結果的に一番安く安全です。EBSボリューム選定とあわせて、初期設定段階で暗号化を織り込んでください。
08鍵設計の判断表
最後に、どの鍵タイプを選ぶかの判断軸を表に整理します。迷ったらこの軸で切り分けてください。
- 制御・監査が必須(コンプライアンス要件、クロスアカウント共有、独自ローテーション周期) → カスタマーマネージドキー(CMK)。月額と使用料は発生するが、CloudTrailで復号を追跡でき、削除・無効化の権限を握れる。
- 同一アカウント内で使えれば十分・鍵管理の手間を減らしたい → AWSマネージドキー。存在は無料、年1回自動ローテーション、ただしポリシー変更・クロスアカウント共有・独自ローテーションは不可。
- 暗号化されていれば十分・監査も制御も不要 → AWS所有キー(多くの新サービスのデフォルト)。完全無料だが、監査も削除もできない。
実運用では、これらを混在させるのが普通です。機密データのバケットや本番DBはCML、内部ログや一時データはAWSマネージドキー、といった具合に、データの重要度とコストのバランスで割り当てます。全部をCMLにすると鍵の保管料とリクエスト課金、ポリシー保守が膨らむので、「本当に制御が要るデータはどれか」を先に決めるのが設計の勘所です。Secrets Manager/Parameter StoreやGuardDuty/Security Hub運用と組み合わせて、暗号化・シークレット・検知を一貫した統制として設計すると、監査対応がぐっと楽になります。
—まとめ
KMSの暗号化設計は、次の順で押さえると迷いません。まず鍵の階層(CMK / データキー / エンベロープ暗号化)を理解し、大きなデータはローカルのデータキーで暗号化してKMSへの通信を絞る。次にキーポリシーとIAMの二重統制を理解し、「キーポリシーが委任していないとIAMが効かない」という非対称性を設計に織り込む。ローテーションは既存データの再暗号化不要で、コストも2回目で頭打ち。クロスアカウントは両側の設定が必須でCMK前提。そしてリクエスト課金はスケールで効いてくるため、S3バケットキーのような削減策を最初から検討する。EBS/RDSは「後から暗号化」が高コストなので、新規構築時にデフォルト暗号化をオンにしておく——ここまでを初期設計で決めておけば、KMSはむしろ手のかからない、堅牢な統制基盤になります。
—参考(一次情報)
- AWS KMS keys(CMK・データキー・鍵階層の概念) - AWS Key Management Service Developer Guide
- KMS key access and permissions(キーポリシー・IAM・グラント) - AWS Key Management Service
- Rotate AWS KMS keys(自動・オンデマンドローテーション) - AWS Key Management Service
- AWS Key Management Service Pricing(料金・リクエスト課金・ローテーション課金)
- Reducing the cost of SSE-KMS with Amazon S3 Bucket Keys - Amazon S3
- Allowing users in other accounts to use a KMS key - AWS Key Management Service