11# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
22# SPDX-License-Identifier: Apache-2.0
33"""
4- This example sets up an MRK multi-keyring and an MRK discovery
5- multi-keyring using a custom client supplier.
6-
7- A custom client supplier grants users access to more granular
8- configuration aspects of their authentication details and KMS
9- client. In this example, we create a simple custom client supplier
10- that authenticates with a different IAM role based on the
11- region of the KMS key.
12-
13- This example creates a MRK multi-keyring configured with a custom
14- client supplier using a single MRK and puts an encrypted item to the
15- table. Then, it creates a MRK discovery multi-keyring to decrypt the item
16- and retrieves the item from the table.
17-
18- Running this example requires access to the DDB Table whose name
19- is provided in CLI arguments.
20- This table must be configured with the following
21- primary key configuration:
4+ Example demonstrating Dynamodb Encryption using a custom client supplier.
5+
6+ A custom client supplier grants users access to more granular configuration aspects
7+ of their authentication details and KMS client. The example creates a simple custom
8+ client supplier that authenticates with a different IAM role based on the region
9+ of the KMS key.
10+
11+ Creates a MRK multi-keyring configured with a custom client supplier using a single
12+ MRK and puts an encrypted item to the table. Then, creates a MRK discovery
13+ multi-keyring to decrypt the item and retrieves the item from the table.
14+
15+ Running this example requires access to the DDB Table whose name is provided in
16+ CLI arguments. This table must be configured with the following primary key
17+ configuration:
2218 - Partition key is named "partition_key" with type (S)
2319 - Sort key is named "sort_key" with type (N)
2420"""
2925from aws_cryptographic_material_providers .mpl import AwsCryptographicMaterialProviders
3026from aws_cryptographic_material_providers .mpl .config import MaterialProvidersConfig
3127from aws_cryptographic_material_providers .mpl .models import (
32- CreateAwsKmsMrkMultiKeyringInput ,
3328 CreateAwsKmsMrkDiscoveryMultiKeyringInput ,
29+ CreateAwsKmsMrkMultiKeyringInput ,
3430 DiscoveryFilter ,
3531)
36- from aws_cryptographic_material_providers .mpl .references import IKeyring
3732from aws_dbesdk_dynamodb .encrypted .client import EncryptedClient
3833from aws_dbesdk_dynamodb .structures .dynamodb import (
3934 DynamoDbTableEncryptionConfig ,
4641from .regional_role_client_supplier import RegionalRoleClientSupplier
4742
4843
49- def client_supplier_example (
50- ddb_table_name : str ,
51- key_arn : str ,
52- account_ids : List [str ],
53- regions : List [str ]
54- ) -> None :
44+ def client_supplier_example (ddb_table_name : str , key_arn : str , account_ids : List [str ], regions : List [str ]) -> None :
5545 """
56- Demonstrate how to use a custom client supplier with AWS KMS MRK multi-keyring
57- and AWS KMS MRK discovery multi-keyring.
46+ Demonstrate using custom client supplier with AWS KMS MRK keyrings.
47+
48+ Shows how to use a custom client supplier with AWS KMS MRK multi-keyring and AWS
49+ KMS MRK discovery multi-keyring.
5850
5951 :param ddb_table_name: The name of the DynamoDB table
6052 :param key_arn: The ARN of the AWS KMS key
@@ -69,14 +61,14 @@ def client_supplier_example(
6961 # in a region in the regions list, and the client
7062 # must have the correct permissions to access the replica.
7163 mat_prov = AwsCryptographicMaterialProviders (config = MaterialProvidersConfig ())
72-
64+
7365 # Create the multi-keyring using our custom client supplier
7466 # defined in the RegionalRoleClientSupplier class in this directory.
7567 create_aws_kms_mrk_multi_keyring_input = CreateAwsKmsMrkMultiKeyringInput (
7668 # Note: RegionalRoleClientSupplier will internally use the keyArn's region
7769 # to retrieve the correct IAM role.
7870 client_supplier = RegionalRoleClientSupplier (),
79- generator = key_arn
71+ generator = key_arn ,
8072 )
8173 mrk_keyring_with_client_supplier = mat_prov .create_aws_kms_mrk_multi_keyring (
8274 input = create_aws_kms_mrk_multi_keyring_input
@@ -91,7 +83,7 @@ def client_supplier_example(
9183 attribute_actions_on_encrypt = {
9284 "partition_key" : CryptoAction .SIGN_ONLY , # Our partition attribute must be SIGN_ONLY
9385 "sort_key" : CryptoAction .SIGN_ONLY , # Our sort attribute must be SIGN_ONLY
94- "sensitive_data" : CryptoAction .ENCRYPT_AND_SIGN
86+ "sensitive_data" : CryptoAction .ENCRYPT_AND_SIGN ,
9587 }
9688
9789 # 3. Configure which attributes we expect to be included in the signature
@@ -131,18 +123,15 @@ def client_supplier_example(
131123 sort_key_name = "sort_key" ,
132124 attribute_actions_on_encrypt = attribute_actions_on_encrypt ,
133125 keyring = mrk_keyring_with_client_supplier ,
134- allowed_unsigned_attribute_prefix = unsign_attr_prefix
126+ allowed_unsigned_attribute_prefix = unsign_attr_prefix ,
135127 )
136128
137129 table_configs = {ddb_table_name : table_config }
138130 tables_config = DynamoDbTablesEncryptionConfig (table_encryption_configs = table_configs )
139131
140132 # 5. Create the EncryptedClient
141- ddb_client = boto3 .client ('dynamodb' )
142- encrypted_ddb_client = EncryptedClient (
143- client = ddb_client ,
144- encryption_config = tables_config
145- )
133+ ddb_client = boto3 .client ("dynamodb" )
134+ encrypted_ddb_client = EncryptedClient (client = ddb_client , encryption_config = tables_config )
146135
147136 # 6. Put an item into our table using the above client.
148137 # Before the item gets sent to DynamoDb, it will be encrypted
@@ -153,33 +142,24 @@ def client_supplier_example(
153142 item = {
154143 "partition_key" : {"S" : "clientSupplierItem" },
155144 "sort_key" : {"N" : "0" },
156- "sensitive_data" : {"S" : "encrypt and sign me!" }
145+ "sensitive_data" : {"S" : "encrypt and sign me!" },
157146 }
158147
159- put_response = encrypted_ddb_client .put_item (
160- TableName = ddb_table_name ,
161- Item = item
162- )
148+ put_response = encrypted_ddb_client .put_item (TableName = ddb_table_name , Item = item )
163149
164150 # Demonstrate that PutItem succeeded
165- assert put_response [' ResponseMetadata' ][ ' HTTPStatusCode' ] == 200
151+ assert put_response [" ResponseMetadata" ][ " HTTPStatusCode" ] == 200
166152
167153 # 7. Get the item back from our table using the same keyring.
168154 # The client will decrypt the item client-side using the MRK
169155 # and return the original item.
170- key_to_get = {
171- "partition_key" : {"S" : "clientSupplierItem" },
172- "sort_key" : {"N" : "0" }
173- }
156+ key_to_get = {"partition_key" : {"S" : "clientSupplierItem" }, "sort_key" : {"N" : "0" }}
174157
175- get_response = encrypted_ddb_client .get_item (
176- TableName = ddb_table_name ,
177- Key = key_to_get
178- )
158+ get_response = encrypted_ddb_client .get_item (TableName = ddb_table_name , Key = key_to_get )
179159
180160 # Demonstrate that GetItem succeeded and returned the decrypted item
181- assert get_response [' ResponseMetadata' ][ ' HTTPStatusCode' ] == 200
182- returned_item = get_response [' Item' ]
161+ assert get_response [" ResponseMetadata" ][ " HTTPStatusCode" ] == 200
162+ returned_item = get_response [" Item" ]
183163 assert returned_item ["sensitive_data" ]["S" ] == "encrypt and sign me!"
184164
185165 # 8. Create a MRK discovery multi-keyring with a custom client supplier.
@@ -190,17 +170,12 @@ def client_supplier_example(
190170 # keyrings will use that client supplier configuration.
191171 # In our tests, we make `key_arn` an MRK with a replica, and
192172 # provide only the replica region in our discovery filter.
193- discovery_filter = DiscoveryFilter (
194- partition = "aws" ,
195- account_ids = account_ids
196- )
173+ discovery_filter = DiscoveryFilter (partition = "aws" , account_ids = account_ids )
197174
198175 mrk_discovery_client_supplier_input = CreateAwsKmsMrkDiscoveryMultiKeyringInput (
199- client_supplier = RegionalRoleClientSupplier (),
200- discovery_filter = discovery_filter ,
201- regions = regions
176+ client_supplier = RegionalRoleClientSupplier (), discovery_filter = discovery_filter , regions = regions
202177 )
203-
178+
204179 mrk_discovery_client_supplier_keyring = mat_prov .create_aws_kms_mrk_discovery_multi_keyring (
205180 input = mrk_discovery_client_supplier_input
206181 )
@@ -214,7 +189,7 @@ def client_supplier_example(
214189 attribute_actions_on_encrypt = attribute_actions_on_encrypt ,
215190 # Provide discovery keyring here
216191 keyring = mrk_discovery_client_supplier_keyring ,
217- allowed_unsigned_attribute_prefix = unsign_attr_prefix
192+ allowed_unsigned_attribute_prefix = unsign_attr_prefix ,
218193 )
219194
220195 replica_key_tables_config = {ddb_table_name : replica_key_table_config }
@@ -223,8 +198,7 @@ def client_supplier_example(
223198 )
224199
225200 replica_key_encrypted_client = EncryptedClient (
226- client = ddb_client ,
227- encryption_config = replica_key_tables_encryption_config
201+ client = ddb_client , encryption_config = replica_key_tables_encryption_config
228202 )
229203
230204 # 10. Get the item back from our table using the discovery keyring client.
@@ -235,17 +209,13 @@ def client_supplier_example(
235209 # which uses different IAM roles based on the key region,
236210 # the discovery keyring will use a particular IAM role to decrypt
237211 # based on the region of the KMS key it uses to decrypt.
238- replica_key_key_to_get = {
239- "partition_key" : {"S" : "awsKmsMrkMultiKeyringItem" },
240- "sort_key" : {"N" : "0" }
241- }
212+ replica_key_key_to_get = {"partition_key" : {"S" : "awsKmsMrkMultiKeyringItem" }, "sort_key" : {"N" : "0" }}
242213
243214 replica_key_get_response = replica_key_encrypted_client .get_item (
244- TableName = ddb_table_name ,
245- Key = replica_key_key_to_get
215+ TableName = ddb_table_name , Key = replica_key_key_to_get
246216 )
247217
248218 # Demonstrate that GetItem succeeded and returned the decrypted item
249- assert replica_key_get_response [' ResponseMetadata' ][ ' HTTPStatusCode' ] == 200
250- replica_key_returned_item = replica_key_get_response [' Item' ]
251- assert replica_key_returned_item ["sensitive_data" ]["S" ] == "encrypt and sign me!"
219+ assert replica_key_get_response [" ResponseMetadata" ][ " HTTPStatusCode" ] == 200
220+ replica_key_returned_item = replica_key_get_response [" Item" ]
221+ assert replica_key_returned_item ["sensitive_data" ]["S" ] == "encrypt and sign me!"
0 commit comments