@@ -39,6 +39,12 @@ Required Prerequisites
3939* boto3 >= 1.10.0
4040* attrs
4141
42+ Recommended Prerequisites
43+ =========================
44+
45+ * aws-cryptographic-material-providers: >= TODO.TODO.TODO (TODO-MPL: versionme)
46+ * Requires Python 3.11+.
47+
4248Installation
4349============
4450
@@ -49,42 +55,71 @@ Installation
4955
5056 .. code ::
5157
52- $ pip install aws-encryption-sdk
58+ $ pip install " aws-encryption-sdk[MPL]"
5359
60+ The `[MPL] ` suffix also installs the `AWS Cryptographic Material Providers Library (MPL) `_.
61+ This is a library that contains constructs for encrypting and decrypting your data.
62+ We highly recommend installing the MPL.
63+ However, if you do not wish to install the MPL, omit the `[MPL] ` suffix.
5464
5565Concepts
5666========
57- There are four main concepts that you need to understand to use this library:
67+ There are three main concepts that you need to understand to use this library:
68+
69+ Data Keys
70+ ---------
71+ Data keys are the encryption keys that are used to encrypt your data. If your algorithm suite
72+ uses a key derivation function, the data key is used to generate the key that directly encrypts the data.
73+
74+ Keyrings
75+ --------
76+ Keyrings are resources that generate, encrypt, and decrypt data keys.
77+ You specify a keyring when encrypting and the same or a different keyring when decrypting.
78+
79+ Note: You must also install the `AWS Cryptographic Material Providers Library (MPL) `_ to create and use keyrings.
80+
81+ For more information, see the `AWS Documentation for Keyrings `_.
5882
5983Cryptographic Materials Managers
6084--------------------------------
6185Cryptographic materials managers (CMMs) are resources that collect cryptographic materials and prepare them for
6286use by the Encryption SDK core logic.
6387
64- An example of a CMM is the default CMM, which is automatically generated anywhere a caller provides a master
65- key provider. The default CMM collects encrypted data keys from all master keys referenced by the master key
66- provider.
88+ An example of a CMM is the default CMM,
89+ which is automatically generated anywhere a caller provides a keyring.
90+
91+ Note: You must also install the `AWS Cryptographic Material Providers Library (MPL) `_
92+ to create and use CMMs that use keyrings.
93+ CMMs that use master key providers have been marked as legacy since v4 of this library.
6794
68- An example of a more advanced CMM is the caching CMM, which caches cryptographic materials provided by another CMM.
95+ Legacy Concepts
96+ ===============
97+ This section describes legacy concepts introduced in earlier versions of this library.
98+ These components have been superseded by new components in the `AWS Cryptographic Material Providers Library (MPL) `_.
99+ Please avoid using these components, and instead use components in the MPL.
69100
70101Master Key Providers
71102--------------------
72103Master key providers are resources that provide master keys.
73- An example of a master key provider is `AWS KMS `_.
74104
75105To encrypt data in this client, a ``MasterKeyProvider `` object must contain at least one ``MasterKey `` object.
76106
77107``MasterKeyProvider `` objects can also contain other ``MasterKeyProvider `` objects.
78108
109+ NOTE: Master key providers are legacy components
110+ and have been superseded by keyrings
111+ provided by the `AWS Cryptographic Material Providers Library (MPL) `_.
112+ Please install this library and migrate master key providers to keyring interfaces.
113+
79114Master Keys
80115-----------
81116Master keys generate, encrypt, and decrypt data keys.
82- An example of a master key is a ` KMS customer master key (CMK) `_.
117+ An example of a master key is an ` AWS KMS key `_.
83118
84- Data Keys
85- ---------
86- Data keys are the encryption keys that are used to encrypt your data. If your algorithm suite
87- uses a key derivation function, the data key is used to generate the key that directly encrypts the data .
119+ NOTE: Master keys are legacy constructs
120+ and have been superseded by keyrings
121+ provided by the ` AWS Cryptographic Material Providers Library (MPL) `_.
122+ Please install this library and migrate master key providers to keyring interfaces .
88123
89124*****
90125Usage
@@ -110,147 +145,71 @@ version of the AWS Encryption SDK, we recommend using the default value.
110145 )
111146
112147
113- You must then create an instance of either a master key provider or a CMM. The examples in this
114- readme use the ``StrictAwsKmsMasterKeyProvider `` class.
148+ You must then create an instance of either a keyring (with the MPL installed) or a CMM.
149+ Note: You must also install the `AWS Cryptographic Material Providers Library (MPL) `_ to use keyrings.
150+ (You may also provide an instance of a legacy master key provider, but this is not recommended.)
151+
115152
153+ AwsKmsMultiKeyring
154+ ==================
116155
117- StrictAwsKmsMasterKeyProvider
118- =============================
119- A ``StrictAwsKmsMasterKeyProvider `` is configured with an explicit list of AWS KMS
120- CMKs with which to encrypt and decrypt data. On encryption, it encrypts the plaintext with all
121- configured CMKs. On decryption, it only attempts to decrypt ciphertexts that have been wrapped
122- with a CMK that matches one of the configured CMK ARNs.
156+ An ``AwsKmsMultiKeyring `` is configured with a generator keyring and a list of
157+ child keyrings of type ``AwsKmsKeyring ``. The effect is like using several keyrings
158+ in a series. When you use a multi-keyring to encrypt data, any of the wrapping keys
159+ in any of its keyrings can decrypt that data.
123160
124- To create a ``StrictAwsKmsMasterKeyProvider `` you must provide one or more CMKs. For providers that will only
125- be used for encryption, you can use any valid `KMS key identifier `_. For providers that will be used for decryption, you
126- must use the key ARN; key ids, alias names, and alias ARNs are not supported.
161+ On encryption, the generator keyring generates and encrypts the plaintext data key.
162+ Then, all of the wrapping keys in all of the child keyrings encrypt the same plaintext data key.
163+ The final `encrypted message `_ will include a copy of the data key encrypted by each configured key.
164+ On decryption, the AWS Encryption SDK uses the keyrings to try to decrypt one of the encrypted data keys.
165+ The keyrings are called in the order that they are specified in the multi-keyring.
166+ Processing stops as soon as any key in any keyring can decrypt an encrypted data key.
127167
128- Because the ``StrictAwsKmsMasterKeyProvider `` uses the `boto3 SDK `_ to interact with `AWS KMS `_,
168+ An individual ``AwsKmsKeyring `` in an ``AwsKmsMultiKeyring `` is configured with an
169+ AWS KMS key ARN.
170+ For keyrings that will only be used for encryption,
171+ you can use any valid `KMS key identifier `_.
172+ For providers that will be used for decryption,
173+ you must use the key ARN.
174+ Key ids, alias names, and alias ARNs are not supported for decryption.
175+
176+ Because the ``AwsKmsMultiKeyring `` uses the `boto3 SDK `_ to interact with `AWS KMS `_,
129177it requires AWS Credentials.
130178To provide these credentials, use the `standard means by which boto3 locates credentials `_ or provide a
131- pre-existing instance of a ``botocore session `` to the ``StrictAwsKmsMasterKeyProvider ``.
179+ pre-existing instance of a ``botocore session `` to the ``AwsKmsMultiKeyring ``.
132180This latter option can be useful if you have an alternate way to store your AWS credentials or
133181you want to reuse an existing instance of a botocore session in order to decrease startup costs.
182+ You can also add KMS keys from multiple regions to the ``AwsKmsMultiKeyring ``.
134183
135- If you configure the the `` StrictAwsKmsMasterKeyProvider `` with multiple CMKs, the ` final message `_
136- will include a copy of the data key encrypted by each configured CMK .
184+ See ` examples/src/aws_kms_multi_keyring_example.py `_ for a code example configuring and using
185+ a `` AwsKmsMultiKeyring `` with the `` EncryptionSDKClient `` .
137186
138- .. code :: python
139-
140- import aws_encryption_sdk
141-
142- kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids = [
143- ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
144- ' arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
145- ])
146-
147- You can add CMKs from multiple regions to the ``StrictAwsKmsMasterKeyProvider ``.
148-
149- .. code :: python
150-
151- import aws_encryption_sdk
152-
153- kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids = [
154- ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
155- ' arn:aws:kms:us-west-2:3333333333333:key/33333333-3333-3333-3333-333333333333' ,
156- ' arn:aws:kms:ap-northeast-1:4444444444444:key/44444444-4444-4444-4444-444444444444'
157- ])
158-
159-
160- DiscoveryAwsKmsMasterKeyProvider
161- ================================
162- We recommend using a ``StrictAwsKmsMasterKeyProvider `` in order to ensure that you can only
163- encrypt and decrypt data using the AWS KMS CMKs you expect. However, if you are unable to
164- explicitly identify the AWS KMS CMKs that should be used for decryption, you can instead
165- use a ``DiscoveryAwsKmsMasterKeyProvider `` for decryption operations. This provider
187+ AwsKmsDiscoveryKeyring
188+ ======================
189+ We recommend using an ``AwsKmsMultiKeyring `` in order to ensure that you can only
190+ encrypt and decrypt data using the AWS KMS key ARN you expect. However, if you are unable to
191+ explicitly identify the AWS KMS key ARNs that should be used for decryption, you can instead
192+ use an ``AwsKmsDiscoveryKeyring `` for decryption operations. This provider
166193attempts decryption of any ciphertexts as long as they match a ``DiscoveryFilter `` that
167194you configure. A ``DiscoveryFilter `` consists of a list of AWS account ids and an AWS
168195partition.
196+ If you do not want to filter the set of allowed accounts, you can also omit the ``discovery_filter `` argument.
169197
170- .. code :: python
198+ Note that an `` AwsKmsDiscoveryKeyring `` cannot be used for encryption operations.
171199
172- import aws_encryption_sdk
173- from aws_encryption_sdk.key_providers.kms import DiscoveryFilter
200+ See ` examples/src/aws_kms_discovery_keyring_example.py `_ for a code example configuring and using
201+ an `` AwsKmsDiscoveryKeyring `` with the `` EncryptionSDKClient ``.
174202
175- discovery_filter = DiscoveryFilter(
176- account_ids = [' 222222222222' , ' 333333333333' ],
177- partition = ' aws'
178- )
179- kms_key_provider = aws_encryption_sdk.DiscoveryAwsKmsMasterKeyProvider(
180- discovery_filter = discovery_filter
181- )
182-
183- If you do not want to filter the set of allowed accounts, you can also omit the ``discovery_filter `` argument.
184-
185- Note that a ``DiscoveryAwsKmsMasterKeyProvider `` cannot be used for encryption operations.
186203
187204Encryption and Decryption
188205=========================
189- After you create an instance of an ``EncryptionSDKClient `` and a ``MasterKeyProvider ``, you can use either of
190- the client's two ``encrypt ``/``decrypt `` functions to encrypt and decrypt your data.
191-
192- .. code :: python
193-
194- import aws_encryption_sdk
195- from aws_encryption_sdk.identifiers import CommitmentPolicy
196-
197- client = aws_encryption_sdk.EncryptionSDKClient(
198- commitment_policy = CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
199- )
200-
201- kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids = [
202- ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
203- ' arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
204- ])
205- my_plaintext = b ' This is some super secret data! Yup, sure is!'
206-
207- my_ciphertext, encryptor_header = client.encrypt(
208- source = my_plaintext,
209- key_provider = kms_key_provider
210- )
211-
212- decrypted_plaintext, decryptor_header = client.decrypt(
213- source = my_ciphertext,
214- key_provider = kms_key_provider
215- )
216-
217- assert my_plaintext == decrypted_plaintext
218- assert encryptor_header.encryption_context == decryptor_header.encryption_context
219-
220- You can provide an `encryption context `_: a form of additional authenticating information.
221-
222- .. code :: python
223-
224- import aws_encryption_sdk
225- from aws_encryption_sdk.identifiers import CommitmentPolicy
226-
227- client = aws_encryption_sdk.EncryptionSDKClient(
228- commitment_policy = CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
229- )
206+ After you create an instance of an ``EncryptionSDKClient `` and a ``Keyring ``, you can use
207+ the client's ``encrypt `` and ``decrypt `` functions to encrypt and decrypt your data.
230208
231- kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids = [
232- ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
233- ' arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
234- ])
235- my_plaintext = b ' This is some super secret data! Yup, sure is!'
236-
237- my_ciphertext, encryptor_header = client.encrypt(
238- source = my_plaintext,
239- key_provider = kms_key_provider,
240- encryption_context = {
241- ' not really' : ' a secret' ,
242- ' but adds' : ' some authentication'
243- }
244- )
245-
246- decrypted_plaintext, decryptor_header = client.decrypt(
247- source = my_ciphertext,
248- key_provider = kms_key_provider
249- )
250-
251- assert my_plaintext == decrypted_plaintext
252- assert encryptor_header.encryption_context == decryptor_header.encryption_context
209+ You can also provide an `encryption context `_: a form of additional authenticating information.
253210
211+ See code in the `examples/src/ `_ directory for code examples configuring and using
212+ keyrings and encryption context with the ``EncryptionSDKClient ``.
254213
255214Streaming
256215=========
@@ -259,57 +218,19 @@ memory at once, you can use this library's streaming clients directly. The strea
259218file-like objects, and behave exactly as you would expect a Python file object to behave,
260219offering context manager and iteration support.
261220
262- .. code :: python
263-
264- import aws_encryption_sdk
265- from aws_encryption_sdk.identifiers import CommitmentPolicy
266- import filecmp
267-
268- client = aws_encryption_sdk.EncryptionSDKClient(
269- commitment_policy = CommitmentPolicy.FORBID_ENCRYPT_ALLOW_DECRYPT
270- )
271-
272- kms_key_provider = aws_encryption_sdk.StrictAwsKmsMasterKeyProvider(key_ids = [
273- ' arn:aws:kms:us-east-1:2222222222222:key/22222222-2222-2222-2222-222222222222' ,
274- ' arn:aws:kms:us-east-1:3333333333333:key/33333333-3333-3333-3333-333333333333'
275- ])
276- plaintext_filename = ' my-secret-data.dat'
277- ciphertext_filename = ' my-encrypted-data.ct'
278-
279- with open (plaintext_filename, ' rb' ) as pt_file, open (ciphertext_filename, ' wb' ) as ct_file:
280- with client.stream(
281- mode = ' e' ,
282- source = pt_file,
283- key_provider = kms_key_provider
284- ) as encryptor:
285- for chunk in encryptor:
286- ct_file.write(chunk)
287-
288- new_plaintext_filename = ' my-decrypted-data.dat'
289-
290- with open (ciphertext_filename, ' rb' ) as ct_file, open (new_plaintext_filename, ' wb' ) as pt_file:
291- with client.stream(
292- mode = ' d' ,
293- source = ct_file,
294- key_provider = kms_key_provider
295- ) as decryptor:
296- for chunk in decryptor:
297- pt_file.write(chunk)
298-
299- assert filecmp.cmp(plaintext_filename, new_plaintext_filename)
300- assert encryptor.header.encryption_context == decryptor.header.encryption_context
221+ See `examples/src/file_streaming_example.py `_ for a code example streaming data to and from files.
301222
302223Performance Considerations
303224==========================
304225Adjusting the frame size can significantly improve the performance of encrypt/decrypt operations with this library.
305226
306- Processing each frame in a framed message involves a certain amount of overhead. If you are encrypting a large file,
307- increasing the frame size can offer potentially significant performance gains. We recommend that you tune these values
227+ Processing each frame in a framed message involves a certain amount of overhead. If you are encrypting a large file,
228+ increasing the frame size can offer potentially significant performance gains. We recommend that you tune these values
308229to your use-case in order to obtain peak performance.
309230
310231Thread safety
311232==========================
312- The ``EncryptionSDKClient `` and all provided ``CryptoMaterialsManager `` are thread safe.
233+ The ``EncryptionSDKClient `` and all provided ``CryptoMaterialsManager `` in this library are thread safe.
313234But instances of ``BaseKMSMasterKeyProvider `` MUST not be shared between threads,
314235for the reasons outlined in `the boto3 docs <https://boto3.amazonaws.com/v1/documentation/api/latest/guide/resources.html#multithreading-or-multiprocessing-with-resources >`_.
315236
@@ -323,17 +244,28 @@ Finally, while the ``CryptoMaterialsCache`` is thread safe,
323244sharing entries in that cache across threads needs to be done carefully
324245(see the !Note about partition name `in the API Docs <https://aws-encryption-sdk-python.readthedocs.io/en/latest/generated/aws_encryption_sdk.materials_managers.caching.html#aws_encryption_sdk.materials_managers.caching.CachingCryptoMaterialsManager >`_).
325246
247+ **Important: ** Components from the `AWS Cryptographic Material Providers Library (MPL) `_
248+ have separate thread safety considerations.
249+ For more information, see the note on thread safety in that project's README (TODO-MPL: link)
250+
251+
326252.. _AWS Encryption SDK : https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html
327253.. _cryptography : https://cryptography.io/en/latest/
328254.. _cryptography installation guide : https://cryptography.io/en/latest/installation/
329255.. _Read the Docs : http://aws-encryption-sdk-python.readthedocs.io/en/latest/
330256.. _GitHub : https://github.com/aws/aws-encryption-sdk-python/
331257.. _AWS KMS : https://docs.aws.amazon.com/kms/latest/developerguide/overview.html
332- .. _ KMS customer master key (CMK) : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys
258+ .. _ AWS KMS key : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys
333259.. _KMS key identifier : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#key-id
334260.. _boto3 SDK : https://boto3.readthedocs.io/en/latest/
335261.. _standard means by which boto3 locates credentials : https://boto3.readthedocs.io/en/latest/guide/configuration.html
336- .. _ final message : https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html
262+ .. _ encrypted message : https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html
337263.. _encryption context : https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context
338264.. _Security issue notifications : ./CONTRIBUTING.md#security-issue-notifications
339265.. _Support Policy : ./SUPPORT_POLICY.rst
266+ .. _AWS Cryptographic Material Providers Library (MPL) : https://github.com/aws/aws-cryptographic-material-providers-library
267+ .. _AWS Documentation for Keyrings : https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/choose-keyring.html
268+ .. _examples/src/aws_kms_multi_keyring_example.py : https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/aws_kms_multi_keyring_example.py
269+ .. _examples/src/aws_kms_discovery_keyring_example.py : https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/aws_kms_discovery_keyring_example.py
270+ .. _examples/src/ : https://github.com/aws/aws-encryption-sdk-python/tree/master/examples/src/
271+ .. _examples/src/file_streaming_example.py : https://github.com/aws/aws-encryption-sdk-python/blob/master/examples/src/file_streaming_example.py
0 commit comments