AWS KMSのキーポリシーとGrantによるアクセス制御

AWS KMSのキーポリシー、IAMポリシー、キー管理者と利用者の権限分離、S3のSSE-KMSオブジェクトを取得する際の許可、Grantの委任・即時利用・取消しをDVA向けに詳しく解説します。

学習順Step 12 / 101サービスKMS試験ドメインセキュリティ

AWS KMSのキーポリシーとGrant

AWS Key Management Service(AWS KMS)では、KMSキーを誰が管理し、誰が暗号化・復号などに使えるかをポリシーとGrantで制御します。暗号化されたデータを読み取る処理では、データ側のアクセス許可だけでなく、そのデータを保護するKMSキーを使う許可も必要です。

アクセス制御を設計するときは、キーそのものに付けるキーポリシー、IAMロールなどに付けるIAMポリシー、必要な操作だけを個別のプリンシパルへ委任するGrantを区別します。これらは代替関係とは限らず、同じリクエストに対して複数の許可が整合していることが求められます。

キーポリシーの役割

キーポリシーは、特定のKMSキーに付けるリソースベースポリシーです。KMSキーには必ず一つのキーポリシーがあり、ポリシーのステートメントで、どのAWSプリンシパルがそのキーに対してどの操作を実行できるかを定義します。キーポリシーはJSON形式で記述し、通常のIAMポリシーと同様に Effect、Action、Principal、Resource、必要に応じて Condition などを使います。

KMSのアクセス制御で特に重要なのは、IAMポリシーにAllowを書くだけでは、必ずしもKMSキーの利用許可にならないことです。キーポリシーがアカウントにIAMポリシーを通じたアクセス許可を委任していない場合、IAMのAllowはキーへのアクセスを成立させません。反対に、キーポリシーがIAMへの委任を認めている場合でも、実際に要求するIAMロールに必要なIAM許可が必要です。いずれの場合も明示的なDenyなどの制限があれば拒否されます。

デフォルトのキーポリシーは作成方法で異なる

AWS KMS APIやSDKからキーを作成し、キーポリシーを指定しない場合、KMSはキーを所有するAWSアカウントに対してIAMポリシーでアクセスを許可できるステートメントを含む、シンプルなデフォルトキーポリシーを設定します。このステートメントはアカウントにキーへの管理権限を与え、アカウント内のIAMポリシーによる権限付与を有効にする役割があります。

一方、AWSマネジメントコンソールから作成すると、アカウントにIAM委任を許すステートメントに加えて、キー管理者やキー利用者を指定したステートメントなどが含まれる形でポリシーが構成されます。どちらの場合も「KMSに関するすべての操作が初めから誰にでも許可される」という意味ではありません。どのPrincipalがどの操作を実行できるのか、実際のキーポリシーを確認してください。

また、キーポリシーはリージョン単位です。あるリージョンのKMSキーに設定したキーポリシーは、別リージョンのキーを制御しません。

キー管理者とキー利用者を分ける

KMSキーに必要な権限は、キーのライフサイクルや設定を管理する操作と、アプリケーションが暗号処理のためにキーを使う操作に分けて設計します。すべての操作を一つのロールに許可すると、アプリケーション侵害時にキーのポリシー変更や無効化まで行われるリスクがあります。

役割 操作の例 主な目的
キー管理者 kms:Create*、kms:Describe*、kms:EnableKey、kms:DisableKey、kms:PutKeyPolicy、kms:ScheduleKeyDeletion、kms:CancelKeyDeletion キーの設定、権限、状態、削除予定などの管理
キー利用者 kms:Encrypt、kms:Decrypt、kms:ReEncrypt*、kms:GenerateDataKey*、kms:DescribeKey アプリケーションによる暗号化、復号、データキー生成など

表のアクションは権限を分類するための例です。キー管理者が必ずすべての管理アクションを持つ必要があるわけではなく、キー利用者にもすべての暗号操作を許可する必要はありません。実際の用途で必要なアクションだけを選び、可能なら対象のキー、呼び出し元サービス、暗号化コンテキストなどの条件で範囲を限定します。たとえば復号だけを行う処理に kms:* を許可するのではなく、必要なキーに対する kms:Decrypt に絞ります。

キーポリシーの例

次の例は、架空のLambda実行ロールをキー管理者と暗号化利用者に分けて指定する、カスタマー管理キー用のキーポリシーの一部です。アカウントのIAMポリシー委任を有効にするステートメントと、ロールごとの直接許可を分けています。実際の環境ではアカウントIDやロールARNを置き換え、既存ポリシーとの関係を確認してください。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "EnableAccountIAMPermissions",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::555566667777:root"
      },
      "Action": "kms:*",
      "Resource": "*"
    },
    {
      "Sid": "AllowKeyAdministrators",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::555566667777:role/KeyOperationsRole"
      },
      "Action": [
        "kms:DescribeKey",
        "kms:EnableKey",
        "kms:DisableKey",
        "kms:PutKeyPolicy",
        "kms:ScheduleKeyDeletion",
        "kms:CancelKeyDeletion"
      ],
      "Resource": "*"
    },
    {
      "Sid": "AllowApplicationToDecrypt",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::555566667777:role/InvoiceProcessorRole"
      },
      "Action": [
        "kms:Decrypt",
        "kms:DescribeKey"
      ],
      "Resource": "*"
    }
  ]
}

KMSのキーポリシーでは、Resource: "*" はそのポリシーが設定されたKMSキーを指します。これは、IAMアイデンティティポリシーでワイルドカードを使う場合と同じ意味ではありません。ポリシーが対象にするキーと Principal を照合してください。

アカウントへの委任ステートメントは、IAMポリシーがキーへの許可を追加できるようにするものです。上の例では、アプリケーション利用ロールに対するキーポリシーの直接許可も含めているため、実際の環境では一つの許可方式に整理できます。キーポリシーがアカウントへのIAM委任を認めている構成なら、利用ロールに対する暗号操作の権限をIAMポリシー側に置く設計も可能です。

S3のSSE-KMSオブジェクトを取得する

Amazon S3でAWS KMSキーを使うサーバー側暗号化(SSE-KMS)を設定したオブジェクトをダウンロードする場合、少なくとも二つの種類の認可を確認します。

  1. S3のオブジェクト読み取り:リクエスト元に対象オブジェクトへの s3:GetObject を許可する。
  2. KMSの復号:リクエスト元に、そのオブジェクトの暗号化に使われたKMSキーに対する kms:Decrypt を許可する。

S3バケットポリシーは、S3オブジェクトへのアクセスを制御します。KMSキーポリシーは、KMSキーを利用できる主体を制御します。バケットポリシーに s3:GetObject を許可しただけではKMSキーの復号権限は得られず、キーポリシーが復号を許可してもS3オブジェクトを読む許可がなければ取得できません。さらに、呼び出し元のIAMロールに必要な権限があり、明示的Denyや他の制限がないことを確認します。

たとえば、注文データを処理するLambda関数が、SSE-KMSで暗号化されたS3オブジェクトを読む構成では、Lambdaの実行ロールに対象キーへの kms:Decrypt と対象オブジェクトへの s3:GetObject を許可します。キーポリシーはそのロールの復号を認め、S3バケット側ではそのロールからの読み取りを許可します。キーの設定によっては、キーポリシーがアカウントへのIAM委任を有効にし、ロール側のIAMポリシーで復号を許可する構成にできます。

SSE-KMSで暗号化されたS3オブジェクトの取得に必要なS3とKMSの認可

通常のSSE-KMSオブジェクトのGETでは、アプリケーションがS3 APIを呼び出し、S3がKMSを利用してオブジェクトの復号を処理します。アプリケーションが平文のKMSキーを受け取るわけではありません。許可のいずれかが不足すると、呼び出し元にはアクセス拒否などのエラーが返されます。調査では、S3の許可だけを確認して終わらず、利用されたKMSキーのARN、リージョン、キーポリシー、実行ロールのIAM権限まで確認します。

この説明はSSE-KMSのオブジェクトを通常のGETで取得するケースです。マルチパートアップロードや追加の暗号化機能では必要なKMS操作が異なる場合があるため、対象のS3機能と操作に対応するAWS公式ドキュメントを確認してください。

Grantで特定の操作を委任する

Grantは、特定のKMSキーに対して、指定したAWSプリンシパルまたはAWSサービスプリンシパルへ、選択した操作を許可する仕組みです。キーを利用するAWSサービスが、暗号化されたリソースの作成や利用に必要な権限を得るために使うこともあります。権限を追加するたびにキーポリシーやIAMポリシーを書き換えずに済み、Grantを不要になった時点で終了できるため、個別の委任を管理しやすくなります。

Grantは、一般に一時的な委任に使えますが、作成したGrantに自動的な有効期限が設定されるわけではありません。短期間だけ必要な権限を安全に扱うには、不要になったGrantを終了させる処理や運用を用意します。また、一つのGrantが許可するのは一つのKMSキーに対する操作です。

Grantで許可できる操作と制約

Grantで指定できる操作には、暗号処理のほか、キー情報の参照やGrant管理に関する操作があります。例は次のとおりです。

  • 暗号処理:Encrypt、Decrypt、ReEncryptFrom、ReEncryptTo、GenerateDataKey、GenerateDataKeyWithoutPlaintext、GenerateDataKeyPair、GenerateDataKeyPairWithoutPlaintext、Sign、Verify、GenerateMac、VerifyMac
  • キー情報の参照:DescribeKey
  • Grant管理:CreateGrant、RetireGrant

利用できる操作はKMSキーの種類・用途によって異なります。Grantで指定できる操作は、キーポリシーやIAMポリシーで許可されるあらゆる管理アクションではありません。たとえば、キーの有効化・無効化、キーポリシーの変更、削除予約などはGrantによって委任できません。キー管理者の権限とGrantを通じた利用権限を混同しないようにします。

Grantには、一つのGrantee Principal(権限を受け取るプリンシパル)を指定します。IAMロールやユーザーなどのAWSプリンシパルを指定する場合は GranteePrincipal、AWSサービスプリンシパルを指定する場合は GranteeServicePrincipal を使用し、両方を同時には指定しません。許可する操作のほか、任意でGrantを退役できるRetiring Principalや、権限を制約する条件を指定できます。

たとえば暗号化コンテキストの条件を付けると、許可したコンテキストに一致する暗号操作にGrantを限定できます。Grantを作成する主体には、対象キーに対する kms:CreateGrant 権限が必要です。Grantを作成できる権限は、他のプリンシパルへキー利用権限を渡す力を持つため、無条件に広く与えず、必要に応じて kms:GrantIsForAWSResource などの条件で用途を絞ります。

CreateGrantから利用終了まで

Grantの作成・利用・終了は次の順に進みます。

  1. 対象キーに対する kms:CreateGrant 権限を持つプリンシパルが CreateGrant を呼び出す。
  2. リクエストで対象キー、Grantee Principal、許可する操作を指定する。必要に応じてRetiring Principalや制約条件も指定する。
  3. KMSがGrantを作成し、Grant IDとGrant Tokenを返す。
  4. Grantの変更がKMS全体へ伝播した後、Granteeは指定された操作を実行できる。伝播前にすぐ使う必要がある場合は、Grant Tokenを対応するKMSリクエストに含める。
  5. Grantが不要になったら、Retiring Principalによる RetireGrant、または権限を持つ主体による RevokeGrant で終了する。

AWS KMS Grantの作成、伝播、Grant Tokenによる即時利用、終了

KMS APIは結果整合性を持ちます。作成したGrantがすべてのKMS処理へ反映されるまで短い遅延があり、伝播前のリクエストではアクセス拒否になることがあります。CreateGrantが返すGrant Tokenを使うと、Grantが全体へ反映されるのを待たずに、対応APIで権限を利用できます。Grantが伝播した後は、通常のリクエストでGrantを特定しなくても、Granteeがその許可を使えます。

RetireGrant はGrantで指定されたRetiring Principalなどが、自ら不要になったGrantを退役させる操作です。RevokeGrant はキー管理者など権限を持つ主体がGrantを取り消す操作です。どちらもGrantによる許可を終了させますが、実行する主体と目的が異なります。Grantを削除した直後も変更が伝播するまで短時間の遅延があり得るため、即時にアクセスが止まると仮定せず、運用上の影響も考慮します。

権限エラーを調べる順序

暗号化されたオブジェクトやアプリケーションでAccessDeniedが発生した場合は、要求を段階に分けて調べると原因を絞りやすくなります。

  1. リクエストで使われたIAMロールまたはAWSサービスプリンシパルを特定する。
  2. S3など、データを提供するサービス上の操作許可とリソースポリシーを確認する。
  3. 実際にデータを暗号化したKMSキーを特定し、同じキーとリージョンを参照しているか確認する。
  4. キーポリシーが要求主体またはアカウントへのIAM委任を許可しているか確認する。
  5. 呼び出し元のIAMポリシーに必要なKMSアクション(読み取りなら通常 kms:Decrypt)があるか確認する。Grantを使う構成では、Grantee・操作・制約・Grantの状態も調べる。
  6. 明示的Deny、権限境界、セッションポリシー、SCP、暗号化コンテキストなどの条件で拒否されていないか確認する。

DVA試験での判断ポイント

  • キーポリシーはKMSキーに付くリソースベースポリシーであり、IAMポリシーだけを追加しても利用許可が成立するとは限らない。キーポリシーがIAMへの委任を認めているか確認する。
  • キー管理者の権限とキー利用者の権限を分離する。kms:PutKeyPolicy やキーの有効化・削除予約などの管理操作を、アプリケーションの暗号処理用ロールへ安易に与えない。
  • SSE-KMSのS3オブジェクトを取得するには、S3の s3:GetObject とKMSキーの kms:Decrypt の両方が必要になる。S3バケットポリシーだけ、またはKMSキーポリシーだけでは完結しない。
  • Grantは特定のKMSキーに対する個別の許可であり、暗号操作だけでなく DescribeKey や一部のGrant管理操作も対象にできる。一方、キーの管理操作全般を委任するものではない。
  • Grantを作成する権限 kms:CreateGrant 自体が、別の主体へキー利用権限を委任できる強い権限である。条件を利用し、Grant作成を必要な用途に限定する。
  • Grant TokenはGrantの伝播を待たずに新しい許可をすぐ使うために利用する。Grantに期限が自動設定されるわけではないため、不要になったGrantは退役または取消しを行う。
  • 同じアカウント内のIAMロール、AWSサービス、クロスアカウント主体では、必要となるキーポリシー・IAMポリシー・Grantの組み合わせを確認する。AWSサービス連携ではサービスごとのKMS統合仕様にも従う。

AWS公式ドキュメント

重要ポイント

  • ▸キーポリシーはKMSキーごとに必須のリソースベースポリシーであり、キーポリシーがIAMへの委任を許可していない限り、IAMのAllowだけではキーへのアクセスを許可できない
  • ▸キー管理者にはキーのポリシーや状態などを管理する操作を、キー利用者にはEncrypt、Decrypt、GenerateDataKeyなどの必要な暗号操作を分けて付与する
  • ▸SSE-KMSのS3オブジェクト取得には、S3オブジェクトの読み取り許可と、KMSキーでのkms:Decrypt許可の両方が必要であり、S3バケットポリシーとKMSキーポリシーは別々に評価される
  • ▸Grantは特定のKMSキーに対して指定した操作をプリンシパルへ委任する許可で、キーポリシーやIAMポリシーを書き換えずに作成・退役・取消しできる
  • ▸Grantの操作には暗号操作のほかDescribeKeyやGrant管理操作も含まれるが、キーの有効化・無効化・ポリシー変更・削除予約などの管理権限はGrantで委任できない
  • ▸Grantは通常、作成後に伝播するまで短い遅延がある。CreateGrantが返すGrant Tokenを対応APIに渡すと、伝播を待たずにGrantを利用できる
  • ▸Grant自体に自動の有効期限はないため、一時的な委任では不要になったGrantをRetireGrantまたはRevokeGrantで終了させる設計が必要

このトピックの学習を完了しますか?

完了状態はいつでも切り替えられます