AWS Key Management Service
開発者ガイド

Amazon DynamoDB で AWS KMS を使用する方法

Amazon DynamoDB は、完全マネージド型のスケーラブルな NoSQL データベースサービスです。DynamoDB は AWS Key Management Service (AWS KMS) を統合して、サーバー側の暗号化機能である保管時の暗号化をサポートします。

保管時の暗号化を使用して、DynamoDB は DynamoDB テーブルがディスクに保管されるたびに、プライマリキーおよびローカルとグローバルのセカンダリインデックスを含むすべてのカスタマーデータを透過的に暗号化します。(テーブルにソートキーが存在する場合、範囲の境界線を示すソートキーの一部が、プレーンテキスト形式でテーブルメタデータに保存されます。) テーブルにアクセスすると、DynamoDB はテーブルデータを透過的に復号化します。暗号化されたテーブルの使用あるいは管理のためにアプリケーションを変更する必要はありません。

保存時の暗号化は、耐久性のあるメディアに保存されるDynamoDB ストリームグローバルテーブルバックアップなどのオブジェクトも保護します。このトピックではテーブルを取り上げていますが、その内容はこれらのオブジェクトにも当てはまります。

DynamoDB テーブルは、すべて暗号化されます。新規のテーブルでも既存のテーブルでも、暗号化を有効または無効にするオプションはありません。デフォルトでは、すべてのテーブルは、DynamoDB サービスアカウントの AWS 所有のカスタマーマスターキー (CMK) を使って暗号化されます。ただし、アカウントの DynamoDB 用の AWS 管理 CMK を使って、テーブルの一部を暗号化するか、全部を暗号化するかを選択できます。保存時の暗号化は、カスタマー管理の CMK をサポートしていません。

注記

2018 年 11 月以前は、保管時の暗号化は、DynamoDB 用の AWS 管理 CMK のみをサポートするオプション機能でした。いずれかの DynamoDB テーブルで保管時の暗号化を有効にした場合、AWS マネジメントコンソール または UpdateTable オペレーションを使って AWS 所有の CMK に切り替えない限り、テーブルは引き続き AWS 管理の CMK で暗号化されます。

DynamoDB へのクライアント側の暗号化

サーバー側の暗号化機能である保管時の暗号化に加えて、AWS は Amazon DynamoDB 暗号化クライアントを提供しています。このクライアント側の暗号化ライブラリは、DynamoDB に送信する前のテーブルデータの保護を有効にします。サーバー側の暗号化では、データは HTTPS 接続で伝送時に暗号化され、DynamoDB エンドポイントで復号された後、DynamoDB に保管される前に再度暗号化されます。クライアント側の暗号化では、ソースから DynamoDB のストレージまで、データをエンドツーエンド保護します。

DynamoDB の暗号化クライアント は保管時の暗号化ととともに使用できます。この戦略が対象となる DynamoDB データに適しているかどうかを判断するには、『Amazon DynamoDB の暗号化クライアント 開発者ガイド』の「クライアント側またはサーバー側の暗号化」を参照してください。

CMK とデータキーの使用

DynamoDB 保管時の暗号化機能は、AWS KMS カスタマーマスターキー (CMK) とデータキーの階層を使ってテーブルデータを保護します。DynamoDB は、耐久性のあるメディアに保存される DynamoDB のストリームやグローバルテーブル、バックアップも、同じキー階層を使って保護します。

カスタマーマスターキー (CMK)

保管時の暗号化は、AWS KMS カスタマーマスターキー (CMK) を使って DynamoDB テーブルを保護します。デフォルトでは AWS 所有の CMK が使用されますが、ユーザーは、AWS アカウントにある DynamoDB (aws/dynamodb) 用の AWS 管理 CMK を使って、テーブルの一部を暗号化するか全部を暗号化するかを選択できます。テーブルを作成または更新するときは、テーブル用の CMK を選択します。各テーブルに対して異なる選択を行うことができます。保管時の暗号化機能は、カスタマー管理の CMK の使用をサポートしていません。

次のいずれかの機能が必要なときは、AWS 管理の CMK を使用します。

  • CMK とそのキーポリシーを表示できます。(キーポリシーの変更はできません)。

  • AWS CloudTrail ログの AWS KMS への DynamoDB API 呼び出しを調べることで、DynamoDB テーブルの暗号化と復号化を監査できます。

ただし、 AWS 所有の CMK は無料です。AWS 管理の CMK では、API 呼び出しごとに料金が発生します。

テーブル用の CMK は、いつでも DynamoDB コンソールで、または UpdateSecret オペレーションを使用して変更できます。CMK を変更すると、新しいテーブルキーが生成されます。次に、新しいテーブルキーを使用してデータ暗号化キーの再暗号化が行われます。

CMK を使用してテーブルキーを作成するプロセスは、どの CMK を選択した場合でも同じです。

テーブルキー

DynamoDB は、テーブルの CMK を使用してそのテーブル用の一意のデータキー (テーブルキー) を生成し、暗号化します。テーブルキーは、暗号化されたテーブルの存続期間中は保持されます。

テーブルキーは、キー暗号化キーとして使用されます。DynamoDB は、このテーブルキーを使って、テーブルデータの暗号化に使うデータ暗号化キーを保護します。DynamoDBはテーブルの基本構造ごとに一意のデータ暗号化キーを生成しますが、複数のテーブル項目が同じデータ暗号化キーによって保護されることがあります。


              保管時の暗号化で DynamoDB テーブルを暗号化する

暗号化されたテーブルにユーザーが初めてアクセスすると、DynamoDB は、CMK を使ってテーブルキーを復号化するよう AWS KMS にリクエストを送信します。その後、プレーンテキストテーブルキーを使用してデータ暗号化キーを復号化し、プレーンテキストデータ暗号化キーを使用してテーブルデータを復号化します。

DynamoDB は、テーブルキーを生成して使用し、テーブルキーと暗号化キーを AWS KMS の外部に保管します。これによって、Advanced Encryption Standard (AES) 暗号化および 256 ビット暗号化キーのすべてのキーが保護されます。続いて、暗号化されたキーを暗号化されたデータと一緒に保存します。これらのキーおよびデータは、必要なときにテーブルデータの暗号化に使用できます。

テーブルキーキャッシュ

すべての DynamoDB オペレーションで AWS KMS を呼び出すことを回避するために、DynamoDB は各接続のプレーンテキストテーブルキーをメモリにキャッシュします。DynamoDB は 5 分以上のアイドル状態が続いた場合にキャッシュされたテーブルキーへのリクエストを取得し、テーブルキーを復号化する新しいリクエストを AWS KMS に送信します。この呼び出しは、テーブルキーの暗号化を求める前回のリクエスト以降に AWS KMS または AWS Identity and Access Management (IAM) で CMK のアクセスポリシーに加えられた変更をすべてキャプチャします。

AWS 管理 CMK の使用の許可

アカウントで AWS 管理の CMK を使って DynamoDB テーブルを保護する場合は、その CMK のポリシーが、ユーザーに代わって使用するための DynamoDB アクセス許可を付与している必要があります。DynamoDB 用の AWS 管理 CMK の認証コンテキストは、そのキーポリシーを含み、使用許可を委任する権限を付与します。

AWS 管理の CMK はアカウントにあるため、ポリシーと許可を表示して確認できます。ただし、AWS によって管理されているため、ポリシーを変更することはできません。

DynamoDB は、デフォルトの AWS 所有 CMK を使って AWS アカウントの DynamoDB テーブルを保護する際、追加の承認を必要としません。

CMK キーポリシー

DynamoDB が暗号化オペレーションに DynamoDB (aws/dynamodb) 用 AWS 管理 CMK を使用するとき、それは、DynamoDB リソースにアクセス中のユーザーに代わって実行されます。AWS 管理 CMK のキーポリシーは、アカウントのすべてのユーザーに、AWS 管理 CMK を使用して指定のオペレーションを実行することを許可します。ただし、許可は DynamoDB がユーザー名でリクエストを行うときのみに付与されます。キーポリシーの ViaService 条件は、リクエストが DynamoDB サービスに由来している場合を除き、どのユーザーに対しても AWS 管理 CMK の使用を許可しません。

このキーポリシーは、すべての AWS 管理キーと同様に、AWS サービスによって確立されます。このポリシーを変更することはできませんが、いつでも表示できます。アカウントの DynamoDB 用 AWS 管理 CMK のキーポリシーを取得するには、GetKeyPolicy オペレーションを使用します。

このキーポリシーのポリシーステートメントには次の効果があります。

  • アカウントのユーザーに、その名で DynamoDB からリクエストを受信したときのみに、DynamoDB 用の AWS 管理 CMK を使用して暗号化オペレーションを行うことができるようにします。また、このポリシーは、ユーザーが CMK の許可を作成できるようにします。

  • AWS アカウントのルートユーザーに対し、DynamoDB 用の AWS 管理 CMK のプロパティを表示することと、DynamoDB に与えた CMK の使用許可を取り消すことを許可します。DynamoDB は、継続的なメンテナンスオペレーションのための許可を使用します。

  • DynamoDB が読み取り専用オペレーションを実行して、アカウントにある DynamoDB 用の AWS 管理 CMK を取得できるようにします。

{ "Version" : "2012-10-17", "Id" : "auto-dynamodb-1", "Statement" : [ { "Sid" : "Allow access through Amazon DynamoDB for all principals in the account that are authorized to use Amazon DynamoDB", "Effect" : "Allow", "Principal" : { "AWS" : "*" }, "Action" : [ "kms:Encrypt", "kms:Decrypt", "kms:ReEncrypt*", "kms:GenerateDataKey*", "kms:CreateGrant", "kms:DescribeKey" ], "Resource" : "*", "Condition" : { "StringEquals" : { "kms:CallerAccount" : "111122223333", "kms:ViaService" : "dynamodb.us-west-2.amazonaws.com" } } }, { "Sid" : "Allow direct access to key metadata to the account", "Effect" : "Allow", "Principal" : { "AWS" : "arn:aws:iam::111122223333:root" }, "Action" : [ "kms:Describe*", "kms:Get*", "kms:List*", "kms:RevokeGrant" ], "Resource" : "*" }, { "Sid" : "Allow DynamoDB Service with service principal name dynamodb.amazonaws.com to describe the key directly", "Effect" : "Allow", "Principal" : { "Service" : "dynamodb.amazonaws.com" }, "Action" : [ "kms:Describe*", "kms:Get*", "kms:List*" ], "Resource" : "*" } ] }

DynamoDB への権限付与を使用する

キーポリシーに加えて、DynamoDB では、権限の付与を使用して DynamoDB 用の AWS 管理 CMK (aws/dynamodb) にアクセス許可を設定します。アカウントの aws/dynamodb CMK に対する権限の付与を表示するには、ListGrants オペレーションを使用します。DynamoDB は、AWS 所有の CMK を使ってテーブルを保護する際に、権限の付与や追加のアクセス許可を必要としません。

DynamoDB は、バックグラウンドシステムメンテナンスおよび継続的なデータの保護タスクを実行するときに、権限付与を使用します。また、テーブルキーの生成に権限付与を使用します。

権限付与は、それぞれ、テーブルに固有です。アカウントに、同じ AWS 管理 CMK を使って暗号化された複数のテーブルがある場合、テーブルごとに、各タイプの権限付与があります。この権限付与は、テーブル名および AWS アカウント ID が含まれる DynamoDB 暗号化コンテキストによって制限され、不要になった場合の権限付与の解除のための許可を含みます。

権限付与を作成するために、DynamoDB は暗号化テーブルを作成したユーザーに代わって CreateGrant を呼び出します。権限付与を作成する許可はキーポリシーに由来し、これによって DynamoDB が承認されたユーザーの代わりにリクエストを行う場合にのみ、アカウントユーザーが CreateGrant 呼び出しを AWS 管理 CMK で行うことを許可します。

また、キーポリシーはアカウントが AWS 管理の CMK で権限付与を解除することを許可します。ただし、アクティブな暗号化テーブルで権限の付与を取り消すと、DynamoDB はテーブルを保護して維持することはできません。

DynamoDB 暗号化コンテキスト

暗号化コンテキスト は、一連のキーと値のペアを含む任意非シークレットデータです。データを暗号化するリクエストに暗号化コンテキストを組み込むと、AWS KMS は暗号化コンテキストを暗号化されたデータに暗号化してバインドします。データを復号化するには、同じ暗号化コンテキストに渡す必要があります。

DynamoDB は、すべての AWS KMS 暗号化オペレーションで同じ暗号化コンテキストを使用します。AWS 管理の CMK を使用して DynamoDB テーブルを保護している場合は、暗号化コンテキストを使って監査レコードやログの中で CMK の使用を特定することができます。また、AWS CloudTrailAmazon CloudWatch Logs のように、プレーンテキストでログに表示されます。

暗号化コンテキストは、ポリシーと権限付与の認証用の条件としても使用できます。DynamoDB は、暗号化テキストを使用してユーザーのアカウントやリージョンでの AWS 管理 CMK へのアクセスを許可する権限付与を制限します。

DynamoDB は AWS KMS へのリクエストで 2 つのキーと値のペアの暗号化コンテキストを使用します。

"encryptionContextSubset": { "aws:dynamodb:tableName": "Books" "aws:dynamodb:subscriberId": "111122223333" }
  • テーブル – 最初のキーと値のペアは DynamoDB が暗号化しているテーブルを識別します。キーは、aws:dynamodb:tableName です。この値は、テーブルの名前です。

    "aws:dynamodb:tableName": "<table-name>"

    例:

    "aws:dynamodb:tableName": "Books"
  • アカウント – 2 番目のキーと値のペアは、AWS アカウントを識別します。キーは、aws:dynamodb:subscriberId です。値は、アカウント ID です。

    "aws:dynamodb:subscriberId": "<account-id>"

    例:

    "aws:dynamodb:subscriberId": "111122223333"

AWS KMS を使用した DynamoDB のモニタリング操作

AWS 管理の CMK を使用して DynamoDB テーブルを保護している場合は、AWS CloudTrail ログを使って、DynamoDB がユーザーに代わって AWS KMS に送信したリクエストを追跡することができます。

このセクションでは、GenerateDataKeyDecrypt、および CreateGrant リクエストを説明します。また、保管時の暗号化に AWS 管理の CMK を使用している場合、DynamoDB は、DescribeKey オペレーションを使ってアカウントとリージョンに aws/dynamodb CMK が存在しているかどうかを特定します。また、RetireGrant オペレーションを使用して、テーブルの削除時に権限付与を削除します。

GenerateDataKey

テーブルで保管時の暗号化を有効にすると、DynamoDB は一意のテーブルキーを作成します。GenerateDataKey リクエストを AWS KMS に送信し、そのテーブル用の CMK を指定します。

GenerateDataKey オペレーションを記録するイベントは、次のようなサンプルイベントになります。ユーザーは、 DynamoDB サービスアカウントです。このパラメーターには、AWS 管理 CMK の Amazon リソースネーム (ARN)、256 ビットキーを要求するキー識別子、およびテーブルと AWS アカウントを識別する暗号化コンテキストが含まれます。

{ "eventVersion": "1.05", "userIdentity": { "type": "AWSService", "invokedBy": "dynamodb.amazonaws.com" }, "eventTime": "2018-02-14T00:15:17Z", "eventSource": "kms.amazonaws.com", "eventName": "GenerateDataKey", "awsRegion": "us-west-2", "sourceIPAddress": "dynamodb.amazonaws.com", "userAgent": "dynamodb.amazonaws.com", "requestParameters": { "encryptionContext": { "aws:dynamodb:tableName": "Services", "aws:dynamodb:subscriberId": "111122223333" }, "keySpec": "AES_256", "keyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab" }, "responseElements": null, "requestID": "229386c1-111c-11e8-9e21-c11ed5a52190", "eventID": "e3c436e9-ebca-494e-9457-8123a1f5e979", "readOnly": true, "resources": [ { "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333", "type": "AWS::KMS::Key" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333", "sharedEventID": "bf915fa6-6ceb-4659-8912-e36b69846aad" }
Decrypt

暗号化された DynamoDB テーブルにアクセスすると、DynamoDB はテーブルキーの復号化が必要となるため、階層の下でキーを復号できます。次に、テーブル内のデータを復号化します。テーブルキーを復号化するには、次が実行されます。DynamoDB は、テーブル用の CMK を指定する AWS KMS に Decrypt リクエストを送信します。

Decrypt オペレーションを記録するイベントは、次のようなサンプルイベントになります。このユーザーは、テーブルにアクセスしている AWS アカウントのプリンシパルです。パラメーターには、暗号化されたテーブルのキー (暗号化テキストの blob として) およびテーブルと AWS アカウントを識別する暗号化コンテキストが含まれます。AWS KMS は暗号化テキストから CMK の ID を取得します。

{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAIGDTESTANDEXAMPLE:user01", "arn": "arn:aws:sts::111122223333:assumed-role/Admin/user01", "accountId": "111122223333", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "2018-02-14T16:42:15Z" }, "sessionIssuer": { "type": "Role", "principalId": "AROAIGDT3HGFQZX4RY6RU", "arn": "arn:aws:iam::111122223333:role/Admin", "accountId": "111122223333", "userName": "Admin" } }, "invokedBy": "dynamodb.amazonaws.com" }, "eventTime": "2018-02-14T16:42:39Z", "eventSource": "kms.amazonaws.com", "eventName": "Decrypt", "awsRegion": "us-west-2", "sourceIPAddress": "dynamodb.amazonaws.com", "userAgent": "dynamodb.amazonaws.com", "requestParameters": { "encryptionContext": { "aws:dynamodb:tableName": "Books", "aws:dynamodb:subscriberId": "111122223333" } }, "responseElements": null, "requestID": "11cab293-11a6-11e8-8386-13160d3e5db5", "eventID": "b7d16574-e887-4b5b-a064-bf92f8ec9ad3", "readOnly": true, "resources": [ { "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333", "type": "AWS::KMS::Key" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }
CreateGrant

AWS 管理 CMK を使って DynamoDB テーブルを保護している場合、DynamoDB は権限付与を使用して、継続するデータの保護とメンテナンスおよび耐久タスクを実行するサービスを許可します。これらの権限付与は、AWS 所有の CMK では必要ありません。

DynamoDB が作成する権限付与はテーブルごとに固有となります。CreateGrant リクエストのプリンシパルは、テーブルを作成したユーザーです。

CreateGrant オペレーションを記録するイベントは、次のようなサンプルイベントになります。このパラメーターには、そのテーブル用の CMK の Amazon リソースネーム (ARN)、プリンシパルの被付与者と廃止プリンシパル (DynamoDB サービス)、およびこの権限付与の範囲内のオペレーションが含まれます。また、指定された暗号化コンテキストを使用するすべての暗号化オペレーションを必要とする制約も含まれています。

{ "eventVersion": "1.05", "userIdentity": { "type": "AssumedRole", "principalId": "AROAIGDTESTANDEXAMPLE:user01", "arn": "arn:aws:sts::111122223333:assumed-role/Admin/user01", "accountId": "111122223333", "accessKeyId": "AKIAIOSFODNN7EXAMPLE", "sessionContext": { "attributes": { "mfaAuthenticated": "false", "creationDate": "2018-02-14T00:12:02Z" }, "sessionIssuer": { "type": "Role", "principalId": "AROAIGDTESTANDEXAMPLE", "arn": "arn:aws:iam::111122223333:role/Admin", "accountId": "111122223333", "userName": "Admin" } }, "invokedBy": "dynamodb.amazonaws.com" }, "eventTime": "2018-02-14T00:15:15Z", "eventSource": "kms.amazonaws.com", "eventName": "CreateGrant", "awsRegion": "us-west-2", "sourceIPAddress": "dynamodb.amazonaws.com", "userAgent": "dynamodb.amazonaws.com", "requestParameters": { "keyId": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "retiringPrincipal": "dynamodb.us-west-2.amazonaws.com", "constraints": { "encryptionContextSubset": { "aws:dynamodb:tableName": "Books", "aws:dynamodb:subscriberId": "111122223333" } }, "granteePrincipal": "dynamodb.us-west-2.amazonaws.com", "operations": [ "DescribeKey", "GenerateDataKey", "Decrypt", "Encrypt", "ReEncryptFrom", "ReEncryptTo", "RetireGrant" ] }, "responseElements": { "grantId": "5c5cd4a3d68e65e77795f5ccc2516dff057308172b0cd107c85b5215c6e48bde" }, "requestID": "2192b82a-111c-11e8-a528-f398979205d8", "eventID": "a03d65c3-9fee-4111-9816-8bf96b73df01", "readOnly": false, "resources": [ { "ARN": "arn:aws:kms:us-west-2:111122223333:key/1234abcd-12ab-34cd-56ef-1234567890ab", "accountId": "111122223333", "type": "AWS::KMS::Key" } ], "eventType": "AwsApiCall", "recipientAccountId": "111122223333" }