Skip to content

Commit abede74

Browse files
chore(MPL): Update README and primary pydocs (#658)
1 parent 8904283 commit abede74

File tree

3 files changed

+204
-200
lines changed

3 files changed

+204
-200
lines changed

README.rst

+108-176
Original file line numberDiff line numberDiff line change
@@ -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+
4248
Installation
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

5565
Concepts
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

5983
Cryptographic Materials Managers
6084
--------------------------------
6185
Cryptographic materials managers (CMMs) are resources that collect cryptographic materials and prepare them for
6286
use 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

70101
Master Key Providers
71102
--------------------
72103
Master key providers are resources that provide master keys.
73-
An example of a master key provider is `AWS KMS`_.
74104

75105
To 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+
79114
Master Keys
80115
-----------
81116
Master 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
*****
90125
Usage
@@ -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`_,
129177
it requires AWS Credentials.
130178
To 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``.
132180
This latter option can be useful if you have an alternate way to store your AWS credentials or
133181
you 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
166193
attempts decryption of any ciphertexts as long as they match a ``DiscoveryFilter`` that
167194
you configure. A ``DiscoveryFilter`` consists of a list of AWS account ids and an AWS
168195
partition.
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

187204
Encryption 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

255214
Streaming
256215
=========
@@ -259,57 +218,19 @@ memory at once, you can use this library's streaming clients directly. The strea
259218
file-like objects, and behave exactly as you would expect a Python file object to behave,
260219
offering 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

302223
Performance Considerations
303224
==========================
304225
Adjusting 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
308229
to your use-case in order to obtain peak performance.
309230

310231
Thread 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.
313234
But instances of ``BaseKMSMasterKeyProvider`` MUST not be shared between threads,
314235
for 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,
323244
sharing 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

Comments
 (0)