From 42def7afaac37a9fccbbf0e0c30187f849fc9e72 Mon Sep 17 00:00:00 2001 From: Ritvik Kapila Date: Fri, 3 May 2024 11:40:55 -0700 Subject: [PATCH 1/5] discovery keyring init and refactoring --- examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py | 0 ...nch_key_id_supplier.py => branch_key_id_supplier_example.py} | 0 ...{hierarchical_keyring.py => hierarchical_keyring_example.py} | 2 +- ...chical_keyring.py => test_i_hierarchical_keyring_example.py} | 2 +- 4 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py rename examples/src/keyrings/{example_branch_key_id_supplier.py => branch_key_id_supplier_example.py} (100%) rename examples/src/keyrings/{hierarchical_keyring.py => hierarchical_keyring_example.py} (99%) rename examples/test/keyrings/{test_i_hierarchical_keyring.py => test_i_hierarchical_keyring_example.py} (86%) diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py new file mode 100644 index 000000000..e69de29bb diff --git a/examples/src/keyrings/example_branch_key_id_supplier.py b/examples/src/keyrings/branch_key_id_supplier_example.py similarity index 100% rename from examples/src/keyrings/example_branch_key_id_supplier.py rename to examples/src/keyrings/branch_key_id_supplier_example.py diff --git a/examples/src/keyrings/hierarchical_keyring.py b/examples/src/keyrings/hierarchical_keyring_example.py similarity index 99% rename from examples/src/keyrings/hierarchical_keyring.py rename to examples/src/keyrings/hierarchical_keyring_example.py index 5642a0b71..1edcab285 100644 --- a/examples/src/keyrings/hierarchical_keyring.py +++ b/examples/src/keyrings/hierarchical_keyring_example.py @@ -53,7 +53,7 @@ from aws_encryption_sdk import CommitmentPolicy from aws_encryption_sdk.exceptions import AWSEncryptionSDKClientError -from .example_branch_key_id_supplier import ExampleBranchKeyIdSupplier +from .branch_key_id_supplier_example import ExampleBranchKeyIdSupplier # TODO-MPL: Remove this as part of removing PYTHONPATH hacks. module_root_dir = '/'.join(__file__.split("/")[:-1]) diff --git a/examples/test/keyrings/test_i_hierarchical_keyring.py b/examples/test/keyrings/test_i_hierarchical_keyring_example.py similarity index 86% rename from examples/test/keyrings/test_i_hierarchical_keyring.py rename to examples/test/keyrings/test_i_hierarchical_keyring_example.py index 5a3adaa1c..6b3f3850a 100644 --- a/examples/test/keyrings/test_i_hierarchical_keyring.py +++ b/examples/test/keyrings/test_i_hierarchical_keyring_example.py @@ -3,7 +3,7 @@ """Test suite for the hierarchical keyring example.""" import pytest -from ...src.keyrings.hierarchical_keyring import encrypt_and_decrypt_with_keyring +from ...src.keyrings.hierarchical_keyring_example import encrypt_and_decrypt_with_keyring pytestmark = [pytest.mark.examples] From a3d09a00b61be71d4c81f6df1ba9e3aaf9b464f9 Mon Sep 17 00:00:00 2001 From: Ritvik Kapila Date: Fri, 3 May 2024 16:08:48 -0700 Subject: [PATCH 2/5] added mrk discovery keyrings --- .../aws_kms_mrk_discovery_keyring_example.py | 179 +++++++++++++++++ ...kms_mrk_discovery_multi_keyring_example.py | 188 ++++++++++++++++++ ...i_aws_kms_mrk_discovery_keyring_example.py | 21 ++ ...kms_mrk_discovery_multi_keyring_example.py | 23 +++ 4 files changed, 411 insertions(+) create mode 100644 examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py create mode 100644 examples/test/keyrings/test_i_aws_kms_mrk_discovery_keyring_example.py create mode 100644 examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py index e69de29bb..b6b4789e0 100644 --- a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py @@ -0,0 +1,179 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +""" +This example sets up the AWS KMS MRK (multi-region key) Discovery Keyring + +AWS KMS discovery keyring is an AWS KMS keyring that doesn't specify any wrapping keys. +The AWS Encryption SDK provides a standard AWS KMS discovery keyring and a discovery keyring +for AWS KMS multi-Region keys. Because it doesn't specify any wrapping keys, a discovery keyring +can't encrypt data. If you use a discovery keyring to encrypt data, alone or in a multi-keyring, +the encrypt operation fails. + +When decrypting, an MRK discovery keyring allows the AWS Encryption SDK to ask AWS KMS to decrypt +any encrypted data key by using the AWS KMS MRK that encrypted it, regardless of who owns or +has access to that AWS KMS key. The call succeeds only when the caller has kms:Decrypt +permission on the AWS KMS MRK. + +The AWS Key Management Service (AWS KMS) MRK keyring interacts with AWS KMS to +create, encrypt, and decrypt data keys with multi-region AWS KMS keys (MRKs). +This example creates a KMS MRK Keyring and then encrypts a custom input EXAMPLE_DATA +with an encryption context. This encrypted ciphertext is then decrypted using an +MRK Discovery keyring. This example also includes some sanity checks for demonstration: +1. Ciphertext and plaintext data are not the same +2. Encryption context is correct in the decrypted message header +3. Decrypted plaintext value matches EXAMPLE_DATA +These sanity checks are for demonstration in the example only. You do not need these in your code. + +For information about using multi-Region keys with the AWS Encryption SDK, see +https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/configure.html#config-mrks + +For more info on KMS MRK (multi-region keys), see the KMS documentation: +https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html + +For more information on how to use KMS Discovery keyrings, see +https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html#kms-keyring-discovery +""" +import sys + +import boto3 +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsMrkKeyringInput, CreateAwsKmsMrkDiscoveryKeyringInput, DiscoveryFilter +from aws_cryptographic_materialproviders.mpl.references import IKeyring +from typing import Dict + +import aws_encryption_sdk +from aws_encryption_sdk import CommitmentPolicy + +# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. +MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) + +sys.path.append(MODULE_ROOT_DIR) + +EXAMPLE_DATA: bytes = b"Hello World" + + +def encrypt_and_decrypt_with_keyring( + mrk_key_id_encrypt: str, + aws_account_id: str, + mrk_encrypt_region: str, + mrk_replica_decrypt_region: str +): + """Demonstrate an encrypt/decrypt cycle using an AWS KMS MRK Discovery keyring. + + Usage: encrypt_and_decrypt_with_keyring(mrk_key_id_encrypt, + aws_account_id, + mrk_encrypt_region, + mrk_replica_decrypt_region) + :param mrk_key_id_encrypt: KMS Key identifier for the KMS key located in your + default region, which you want to use for encryption of your data keys + :type mrk_key_id_encrypt: string + :param aws_account_id: AWS Account ID to use in the discovery filter + :type aws_account_id: string + :param mrk_encrypt_region: AWS Region for encryption of your data keys. This should + be the region of the mrk_key_id_encrypt. + :type mrk_encrypt_region: string + :param mrk_replica_decrypt_region: AWS Region for decryption of your data keys. + This example assumes you have already replicated your mrk_key_id_encrypt to the + region mrk_replica_decrypt_region. Therfore, this mrk_replica_decrypt_region should + be the region of the mrk replica key id. However, since we are using a discovery keyring, + we don't need to provide the mrk replica key id + :type mrk_replica_decrypt_region: string + + For more information on KMS Key identifiers for multi-region keys, see + https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id + """ + # 1. Instantiate the encryption SDK client. + # This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy, + # which enforces that this client only encrypts using committing algorithm suites and enforces + # that this client will only decrypt encrypted messages that were created with a committing + # algorithm suite. + # This is the default commitment policy if you were to build the client as + # `client = aws_encryption_sdk.EncryptionSDKClient()`. + client = aws_encryption_sdk.EncryptionSDKClient( + commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT + ) + + # 2. Create encryption context. + # Remember that your encryption context is NOT SECRET. + # For more information, see + # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + encryption_context: Dict[str, str] = { + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + + # 3. Create the keyring that determines how your data keys are protected. + # Although this example highlights Discovery keyrings, Discovery keyrings cannot + # be used to encrypt, so for encryption we create an MRK keyring without discovery mode. + + # Create a keyring that will encrypt your data, using a KMS MRK in the first region. + mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() + ) + + # Create a boto3 client for KMS in the first region. + encrypt_kms_client = boto3.client('kms', region_name=mrk_encrypt_region) + + encrypt_keyring_input: CreateAwsKmsMrkKeyringInput = CreateAwsKmsMrkKeyringInput( + kms_key_id=mrk_key_id_encrypt, + kms_client=encrypt_kms_client + ) + + encrypt_keyring: IKeyring = mat_prov.create_aws_kms_mrk_keyring( + input=encrypt_keyring_input + ) + + # 4. Encrypt the data with the encryptionContext using the encrypt_keyring. + ciphertext, _ = client.encrypt( + source=EXAMPLE_DATA, + keyring=encrypt_keyring, + encryption_context=encryption_context + ) + + # 5. Demonstrate that the ciphertext and plaintext are different. + # (This is an example for demonstration; you do not need to do this in your own code.) + assert ciphertext != EXAMPLE_DATA, \ + "Ciphertext and plaintext data are the same. Invalid encryption" + + # 6. Now create a Discovery keyring to use for decryption. + # In order to illustrate the MRK behavior of this keyring, we configure + # the keyring to use the second KMS region where the MRK (mrk_key_id_encrypt) is replicated to. + # This example assumes you have already replicated your key, but since we + # are using a discovery keyring, we don't need to provide the mrk replica key id + + # Create a boto3 client for KMS in the second region. + decrypt_kms_client = boto3.client('kms', region_name=mrk_replica_decrypt_region) + + decrypt_discovery_keyring_input: CreateAwsKmsMrkDiscoveryKeyringInput = \ + CreateAwsKmsMrkDiscoveryKeyringInput( + kms_client=decrypt_kms_client, + region=mrk_replica_decrypt_region, + discovery_filter=DiscoveryFilter( + account_ids=[aws_account_id], + partition="aws" + ) + ) + + decrypt_discovery_keyring: IKeyring = mat_prov.create_aws_kms_mrk_discovery_keyring( + input=decrypt_discovery_keyring_input + ) + + # 7. Decrypt your encrypted data using the discovery keyring. + plaintext_bytes, dec_header = client.decrypt( + source=ciphertext, + keyring=decrypt_discovery_keyring + ) + + # 8. Demonstrate that the encryption context is correct in the decrypted message header + # (This is an example for demonstration; you do not need to do this in your own code.) + for k, v in encryption_context.items(): + assert v == dec_header.encryption_context[k], \ + "Encryption context does not match expected values" + + # 9. Demonstrate that the decrypted plaintext is identical to the original plaintext. + # (This is an example for demonstration; you do not need to do this in your own code.) + assert plaintext_bytes == EXAMPLE_DATA diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py new file mode 100644 index 000000000..0e77c49d6 --- /dev/null +++ b/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py @@ -0,0 +1,188 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +""" +This example sets up the AWS KMS MRK (multi-region key) Discovery Multi Keyring + +AWS KMS MRK Discovery Multi Keyring is composed of multiple MRK discovery keyrings. + +AWS KMS discovery keyring is an AWS KMS keyring that doesn't specify any wrapping keys. +The AWS Encryption SDK provides a standard AWS KMS discovery keyring and a discovery keyring +for AWS KMS multi-Region keys. Because it doesn't specify any wrapping keys, a discovery keyring +can't encrypt data. If you use a discovery keyring to encrypt data, alone or in a multi-keyring, +the encrypt operation fails. + +When decrypting, an MRK discovery keyring allows the AWS Encryption SDK to ask AWS KMS to decrypt +any encrypted data key by using the AWS KMS MRK that encrypted it, regardless of who owns or +has access to that AWS KMS key. The call succeeds only when the caller has kms:Decrypt +permission on the AWS KMS MRK. + +The AWS Key Management Service (AWS KMS) MRK keyring interacts with AWS KMS to +create, encrypt, and decrypt data keys with multi-region AWS KMS keys (MRKs). +This example creates a KMS MRK Keyring and then encrypts a custom input EXAMPLE_DATA +with an encryption context. This encrypted ciphertext is then decrypted using an +MRK Discovery Multi keyring. This example also includes some sanity checks for demonstration: +1. Ciphertext and plaintext data are not the same +2. Encryption context is correct in the decrypted message header +3. Decrypted plaintext value matches EXAMPLE_DATA +These sanity checks are for demonstration in the example only. You do not need these in your code. + +For information about using multi-Region keys with the AWS Encryption SDK, see +https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/configure.html#config-mrks + +For more info on KMS MRK (multi-region keys), see the KMS documentation: +https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html + +For more information on how to use KMS Discovery keyrings, see +https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/use-kms-keyring.html#kms-keyring-discovery +""" +import sys + +import boto3 +from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders +from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig +from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsMrkKeyringInput, CreateAwsKmsMrkDiscoveryMultiKeyringInput, DiscoveryFilter +from aws_cryptographic_materialproviders.mpl.references import IKeyring +from typing import Dict + +import aws_encryption_sdk +from aws_encryption_sdk import CommitmentPolicy + +# TODO-MPL: Remove this as part of removing PYTHONPATH hacks. +MODULE_ROOT_DIR = '/'.join(__file__.split("/")[:-1]) + +sys.path.append(MODULE_ROOT_DIR) + +EXAMPLE_DATA: bytes = b"Hello World" + + +def encrypt_and_decrypt_with_keyring( + mrk_key_id_encrypt: str, + mrk_encrypt_region: str, + aws_account_id: str, + aws_regions: str +): + """Demonstrate an encrypt/decrypt cycle using an AWS KMS MRK Discovery Multi keyring. + + Usage: encrypt_and_decrypt_with_keyring(mrk_key_id_encrypt, + mrk_encrypt_region, + aws_account_id, + aws_regions) + :param mrk_key_id_encrypt: KMS Key identifier for the KMS key located in your + default region, which you want to use for encryption of your data keys + :type mrk_key_id_encrypt: string + :param mrk_encrypt_region: AWS Region for encryption of your data keys. This should + be the region of the mrk_key_id_encrypt + :type mrk_encrypt_region: string + :param aws_account_id: AWS Account ID to use in the discovery filter + :type aws_account_id: string + :param aws_regions: AWS Region to use in the the discovery filter + :type aws_regions: string + + For more information on KMS Key identifiers for multi-region keys, see + https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id + """ + # 1. Instantiate the encryption SDK client. + # This builds the client with the REQUIRE_ENCRYPT_REQUIRE_DECRYPT commitment policy, + # which enforces that this client only encrypts using committing algorithm suites and enforces + # that this client will only decrypt encrypted messages that were created with a committing + # algorithm suite. + # This is the default commitment policy if you were to build the client as + # `client = aws_encryption_sdk.EncryptionSDKClient()`. + client = aws_encryption_sdk.EncryptionSDKClient( + commitment_policy=CommitmentPolicy.REQUIRE_ENCRYPT_REQUIRE_DECRYPT + ) + + # 2. Create encryption context. + # Remember that your encryption context is NOT SECRET. + # For more information, see + # https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#encryption-context + encryption_context: Dict[str, str] = { + "encryption": "context", + "is not": "secret", + "but adds": "useful metadata", + "that can help you": "be confident that", + "the data you are handling": "is what you think it is", + } + + # 3. Create the keyring that determines how your data keys are protected. + # Although this example highlights Discovery keyrings, Discovery keyrings cannot + # be used to encrypt, so for encryption we create an MRK keyring without discovery mode. + + # Create a keyring that will encrypt your data, using a KMS MRK in the first region. + mat_prov: AwsCryptographicMaterialProviders = AwsCryptographicMaterialProviders( + config=MaterialProvidersConfig() + ) + + # Create a boto3 client for KMS in the first region. + encrypt_kms_client = boto3.client('kms', region_name=mrk_encrypt_region) + + encrypt_keyring_input: CreateAwsKmsMrkKeyringInput = CreateAwsKmsMrkKeyringInput( + kms_key_id=mrk_key_id_encrypt, + kms_client=encrypt_kms_client + ) + + encrypt_keyring: IKeyring = mat_prov.create_aws_kms_mrk_keyring( + input=encrypt_keyring_input + ) + + # 4. Encrypt the data with the encryptionContext using the encrypt_keyring. + ciphertext, _ = client.encrypt( + source=EXAMPLE_DATA, + keyring=encrypt_keyring, + encryption_context=encryption_context + ) + + # 5. Demonstrate that the ciphertext and plaintext are different. + # (This is an example for demonstration; you do not need to do this in your own code.) + assert ciphertext != EXAMPLE_DATA, \ + "Ciphertext and plaintext data are the same. Invalid encryption" + + # 6. Now create a MRK Discovery Multi Keyring to use for decryption. + # We'll add a discovery filter to limit the set of encrypted data keys + # we are willing to decrypt to only ones created by KMS keys in select + # accounts and the partition `aws`. + # MRK Discovery keyrings also filter encrypted data keys by the region + # the keyring is created with. + decrypt_discovery_multi_keyring_input: CreateAwsKmsMrkDiscoveryMultiKeyringInput = \ + CreateAwsKmsMrkDiscoveryMultiKeyringInput( + regions=aws_regions, + discovery_filter=DiscoveryFilter( + account_ids=[aws_account_id], + partition="aws" + ) + ) + + # This is a Multi Keyring composed of Discovery Keyrings. + # There is a keyring for every region in `regions`. + # All the keyrings have the same Discovery Filter. + # Each keyring has its own KMS Client, which is created for the keyring's region. + decrypt_discovery_keyring: IKeyring = mat_prov.create_aws_kms_mrk_discovery_multi_keyring( + input=decrypt_discovery_multi_keyring_input + ) + + # 7. Decrypt your encrypted data using the discovery multi keyring. + # On Decrypt, the header of the encrypted message (ciphertext) will be parsed. + # The header contains the Encrypted Data Keys (EDKs), which, if the EDK + # was encrypted by a KMS Keyring, includes the KMS Key ARN. + # For each member of the Multi Keyring, every EDK will try to be decrypted until a decryption + # is successful. + # Since every member of the Multi Keyring is a Discovery Keyring: + # Each Keyring will filter the EDKs by the Discovery Filter and the Keyring's region. + # For each filtered EDK, the keyring will attempt decryption with the keyring's client. + # All of this is done serially, until a success occurs or all keyrings have failed + # all (filtered) EDKs. KMS MRK Discovery Keyrings will attempt to decrypt + # Multi Region Keys (MRKs) and regular KMS Keys. + plaintext_bytes, dec_header = client.decrypt( + source=ciphertext, + keyring=decrypt_discovery_keyring + ) + + # 8. Demonstrate that the encryption context is correct in the decrypted message header + # (This is an example for demonstration; you do not need to do this in your own code.) + for k, v in encryption_context.items(): + assert v == dec_header.encryption_context[k], \ + "Encryption context does not match expected values" + + # 9. Demonstrate that the decrypted plaintext is identical to the original plaintext. + # (This is an example for demonstration; you do not need to do this in your own code.) + assert plaintext_bytes == EXAMPLE_DATA diff --git a/examples/test/keyrings/test_i_aws_kms_mrk_discovery_keyring_example.py b/examples/test/keyrings/test_i_aws_kms_mrk_discovery_keyring_example.py new file mode 100644 index 000000000..bc0279066 --- /dev/null +++ b/examples/test/keyrings/test_i_aws_kms_mrk_discovery_keyring_example.py @@ -0,0 +1,21 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Test suite for the AWS KMS MRK Discovery keyring example.""" +import pytest + +from ...src.keyrings.aws_kms_mrk_discovery_keyring_example import encrypt_and_decrypt_with_keyring + +pytestmark = [pytest.mark.examples] + + +def test_encrypt_and_decrypt_with_keyring(): + """Test function for encrypt and decrypt using the AWS KMS MRK Discovery Keyring example.""" + mrk_key_id_encrypt = \ + "arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7" + aws_account_id = "658956600833" + mrk_encrypt_region = "us-east-1" + mrk_replica_decrypt_region = "eu-west-1" + encrypt_and_decrypt_with_keyring(mrk_key_id_encrypt, + aws_account_id, + mrk_encrypt_region, + mrk_replica_decrypt_region) diff --git a/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py b/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py new file mode 100644 index 000000000..c472ab42f --- /dev/null +++ b/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py @@ -0,0 +1,23 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# SPDX-License-Identifier: Apache-2.0 +"""Test suite for the AWS KMS MRK Discovery Multi keyring example.""" +import pytest + +from ...src.keyrings.aws_kms_mrk_discovery_multi_keyring_example import encrypt_and_decrypt_with_keyring + +pytestmark = [pytest.mark.examples] + + +def test_encrypt_and_decrypt_with_keyring(): + """Test function for encrypt and decrypt using the + AWS KMS MRK Discovery Multi Keyring example. + """ + mrk_key_id_encrypt = \ + "arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7" + mrk_encrypt_region = "us-east-1" + aws_account_id = "658956600833" + aws_regions = ["us-west-2", "us-east-1"] + encrypt_and_decrypt_with_keyring(mrk_key_id_encrypt, + mrk_encrypt_region, + aws_account_id, + aws_regions) From 741ca8f53c0196016adb311024ce52b1a91be128 Mon Sep 17 00:00:00 2001 From: Ritvik Kapila Date: Fri, 3 May 2024 16:17:38 -0700 Subject: [PATCH 3/5] fix --- .../src/keyrings/aws_kms_mrk_discovery_keyring_example.py | 6 +++++- .../keyrings/aws_kms_mrk_discovery_multi_keyring_example.py | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py index b6b4789e0..825def114 100644 --- a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py @@ -38,7 +38,11 @@ import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig -from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsMrkKeyringInput, CreateAwsKmsMrkDiscoveryKeyringInput, DiscoveryFilter +from aws_cryptographic_materialproviders.mpl.models import ( + CreateAwsKmsMrkDiscoveryKeyringInput, + CreateAwsKmsMrkKeyringInput, + DiscoveryFilter, +) from aws_cryptographic_materialproviders.mpl.references import IKeyring from typing import Dict diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py index 0e77c49d6..b10d5b6db 100644 --- a/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py @@ -40,7 +40,11 @@ import boto3 from aws_cryptographic_materialproviders.mpl import AwsCryptographicMaterialProviders from aws_cryptographic_materialproviders.mpl.config import MaterialProvidersConfig -from aws_cryptographic_materialproviders.mpl.models import CreateAwsKmsMrkKeyringInput, CreateAwsKmsMrkDiscoveryMultiKeyringInput, DiscoveryFilter +from aws_cryptographic_materialproviders.mpl.models import ( + CreateAwsKmsMrkDiscoveryMultiKeyringInput, + CreateAwsKmsMrkKeyringInput, + DiscoveryFilter, +) from aws_cryptographic_materialproviders.mpl.references import IKeyring from typing import Dict From b4912949fffacc2776f00efd87e2daef1b95329f Mon Sep 17 00:00:00 2001 From: Ritvik Kapila Date: Fri, 3 May 2024 16:21:56 -0700 Subject: [PATCH 4/5] fix flake8 --- .../test_i_aws_kms_mrk_discovery_multi_keyring_example.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py b/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py index c472ab42f..93672b046 100644 --- a/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/test/keyrings/test_i_aws_kms_mrk_discovery_multi_keyring_example.py @@ -9,9 +9,7 @@ def test_encrypt_and_decrypt_with_keyring(): - """Test function for encrypt and decrypt using the - AWS KMS MRK Discovery Multi Keyring example. - """ + """Test function for encrypt and decrypt using AWS KMS MRK Discovery Multi Keyring example.""" mrk_key_id_encrypt = \ "arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7" mrk_encrypt_region = "us-east-1" From 2417a42b9ad493f33937f6e7c0cde181f41be90e Mon Sep 17 00:00:00 2001 From: Ritvik Kapila Date: Mon, 6 May 2024 10:30:16 -0700 Subject: [PATCH 5/5] resolved comments --- .../aws_kms_mrk_discovery_keyring_example.py | 22 ++++++++++--------- ...kms_mrk_discovery_multi_keyring_example.py | 22 ++++++++++--------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py index 825def114..63233a068 100644 --- a/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py +++ b/examples/src/keyrings/aws_kms_mrk_discovery_keyring_example.py @@ -3,17 +3,18 @@ """ This example sets up the AWS KMS MRK (multi-region key) Discovery Keyring -AWS KMS discovery keyring is an AWS KMS keyring that doesn't specify any wrapping keys. -The AWS Encryption SDK provides a standard AWS KMS discovery keyring and a discovery keyring -for AWS KMS multi-Region keys. Because it doesn't specify any wrapping keys, a discovery keyring -can't encrypt data. If you use a discovery keyring to encrypt data, alone or in a multi-keyring, -the encrypt operation fails. +The AWS KMS discovery keyring is an AWS KMS keyring that doesn't specify any wrapping keys. When decrypting, an MRK discovery keyring allows the AWS Encryption SDK to ask AWS KMS to decrypt any encrypted data key by using the AWS KMS MRK that encrypted it, regardless of who owns or has access to that AWS KMS key. The call succeeds only when the caller has kms:Decrypt permission on the AWS KMS MRK. +The AWS Encryption SDK provides a standard AWS KMS discovery keyring and a discovery keyring +for AWS KMS multi-Region keys. Because it doesn't specify any wrapping keys, a discovery keyring +can't encrypt data. If you use a discovery keyring to encrypt data, alone or in a multi-keyring, +the encrypt operation fails. + The AWS Key Management Service (AWS KMS) MRK keyring interacts with AWS KMS to create, encrypt, and decrypt data keys with multi-region AWS KMS keys (MRKs). This example creates a KMS MRK Keyring and then encrypts a custom input EXAMPLE_DATA @@ -27,7 +28,7 @@ For information about using multi-Region keys with the AWS Encryption SDK, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/configure.html#config-mrks -For more info on KMS MRK (multi-region keys), see the KMS documentation: +For more info on KMS MRKs (multi-region keys), see the KMS documentation: https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html For more information on how to use KMS Discovery keyrings, see @@ -63,8 +64,9 @@ def encrypt_and_decrypt_with_keyring( mrk_encrypt_region: str, mrk_replica_decrypt_region: str ): - """Demonstrate an encrypt/decrypt cycle using an AWS KMS MRK Discovery keyring. + """Demonstrate decryption using an AWS KMS MRK Discovery keyring. + Since discovery keyrings cannot be used to encrypt, we use KMS MRK keyring for encryption Usage: encrypt_and_decrypt_with_keyring(mrk_key_id_encrypt, aws_account_id, mrk_encrypt_region, @@ -79,9 +81,9 @@ def encrypt_and_decrypt_with_keyring( :type mrk_encrypt_region: string :param mrk_replica_decrypt_region: AWS Region for decryption of your data keys. This example assumes you have already replicated your mrk_key_id_encrypt to the - region mrk_replica_decrypt_region. Therfore, this mrk_replica_decrypt_region should - be the region of the mrk replica key id. However, since we are using a discovery keyring, - we don't need to provide the mrk replica key id + region mrk_replica_decrypt_region. Therefore, this mrk_replica_decrypt_region should + be the region of the MRK replica. However, since we are using a discovery keyring, + we don't need to provide the replica MRK ID. :type mrk_replica_decrypt_region: string For more information on KMS Key identifiers for multi-region keys, see diff --git a/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py b/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py index b10d5b6db..d8ea9bc4c 100644 --- a/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py +++ b/examples/src/keyrings/aws_kms_mrk_discovery_multi_keyring_example.py @@ -5,17 +5,18 @@ AWS KMS MRK Discovery Multi Keyring is composed of multiple MRK discovery keyrings. -AWS KMS discovery keyring is an AWS KMS keyring that doesn't specify any wrapping keys. -The AWS Encryption SDK provides a standard AWS KMS discovery keyring and a discovery keyring -for AWS KMS multi-Region keys. Because it doesn't specify any wrapping keys, a discovery keyring -can't encrypt data. If you use a discovery keyring to encrypt data, alone or in a multi-keyring, -the encrypt operation fails. +The AWS KMS discovery keyring is an AWS KMS keyring that doesn't specify any wrapping keys. When decrypting, an MRK discovery keyring allows the AWS Encryption SDK to ask AWS KMS to decrypt any encrypted data key by using the AWS KMS MRK that encrypted it, regardless of who owns or has access to that AWS KMS key. The call succeeds only when the caller has kms:Decrypt permission on the AWS KMS MRK. +The AWS Encryption SDK provides a standard AWS KMS discovery keyring and a discovery keyring +for AWS KMS multi-Region keys. Because it doesn't specify any wrapping keys, a discovery keyring +can't encrypt data. If you use a discovery keyring to encrypt data, alone or in a multi-keyring, +the encrypt operation fails. + The AWS Key Management Service (AWS KMS) MRK keyring interacts with AWS KMS to create, encrypt, and decrypt data keys with multi-region AWS KMS keys (MRKs). This example creates a KMS MRK Keyring and then encrypts a custom input EXAMPLE_DATA @@ -29,7 +30,7 @@ For information about using multi-Region keys with the AWS Encryption SDK, see https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/configure.html#config-mrks -For more info on KMS MRK (multi-region keys), see the KMS documentation: +For more info on KMS MRKs (multi-region keys), see the KMS documentation: https://docs.aws.amazon.com/kms/latest/developerguide/multi-region-keys-overview.html For more information on how to use KMS Discovery keyrings, see @@ -63,10 +64,11 @@ def encrypt_and_decrypt_with_keyring( mrk_key_id_encrypt: str, mrk_encrypt_region: str, aws_account_id: str, - aws_regions: str + aws_regions: list[str] ): - """Demonstrate an encrypt/decrypt cycle using an AWS KMS MRK Discovery Multi keyring. + """Demonstrate decryption using an AWS KMS MRK Discovery Multi keyring. + Since discovery keyrings cannot be used to encrypt, we use KMS MRK keyring for encryption Usage: encrypt_and_decrypt_with_keyring(mrk_key_id_encrypt, mrk_encrypt_region, aws_account_id, @@ -79,8 +81,8 @@ def encrypt_and_decrypt_with_keyring( :type mrk_encrypt_region: string :param aws_account_id: AWS Account ID to use in the discovery filter :type aws_account_id: string - :param aws_regions: AWS Region to use in the the discovery filter - :type aws_regions: string + :param aws_regions: AWS Regions to use in the the discovery filter + :type aws_regions: list[string] For more information on KMS Key identifiers for multi-region keys, see https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id