chore: Cdk plus basic ci test#1
Conversation
lucasmcdonald3
left a comment
There was a problem hiding this comment.
Initial skim, I'd also recommend adding linters sooner rather than later. I think the "cool" linters these days are a combination of ruff and black: https://github.com/aws/aws-database-encryption-sdk-dynamodb/blob/python-poc/DynamoDbEncryption/runtimes/python/pyproject.toml#L59-L61
| # There is a newer version, but MPL wants this one. | ||
| cryptography = "^43.0.1" |
There was a problem hiding this comment.
| # There is a newer version, but MPL wants this one. | |
| cryptography = "^43.0.1" |
This is included transitively via MPL
There was a problem hiding this comment.
Ok -- given that you don't need the MPL let me also save you from a mistake I made and set this as a range
| # There is a newer version, but MPL wants this one. | |
| cryptography = "^43.0.1" | |
| # There is a newer version, but MPL wants this one. | |
| cryptography = ">=45.0.1, <46" |
the "^43.0.1" syntax resolves to >=43.0.1, <44 which restricts customers.
When launching MPL-Python, we decided the best thing to do was to drop support for as many older versions as possible of cryptography, so ideally we're launching with the newest support possible. It's easy to decrease the minimum version later on but hard to increase it.
There was a problem hiding this comment.
Do we need to specify an upper bound on future major versions? I feel like it's reasonable to trust the future MVs will be backwards compatible (unless there's a serious security issue in which case we'd need to do some work to upgrade). Any reason we shouldn't just go with cryptography = ">=45.0.6"?
| boto3 = "^1.37.2" | ||
| # There is a newer version, but MPL wants this one. | ||
| cryptography = "^43.0.1" | ||
| aws-cryptographic-material-providers = "^1.7.4" |
There was a problem hiding this comment.
| aws-cryptographic-material-providers = "^1.7.4" | |
| aws-cryptographic-material-providers = "^1.11.1" |
Bump to latest when you get a chance, there are traps in earlier versions
There was a problem hiding this comment.
No, it doesn't, not sure how/why it ended up there. Will remove.
| cryptography = "^43.0.1" | ||
| aws-cryptographic-material-providers = "^1.7.4" | ||
| attrs = "^25.1.0" | ||
| pytest = "^8.4.1" |
There was a problem hiding this comment.
Include this as a test dependency -- check out DBESDK for a good example here
| @@ -0,0 +1,22 @@ | |||
| [tool.poetry] | |||
There was a problem hiding this comment.
You might consider using uv instead of poetry. All the cool projects are using uv these days: https://github.com/astral-sh/uv
poetry is not a great package management system, but it solved some needs specific to Dafny-Python issues. Since you're not generating any Dafny code, you can probably branch out.
| # TODO: I don't know exactly how boto3 works, | ||
| # we maybe instead prefer only using kwargs? | ||
| # Do we need to provide specific arg overloads? |
There was a problem hiding this comment.
Imo, ideally any clients we write should be able to act as drop-in replacements for the boto3 equivalents, which means just using kwargs.
| from typing import List, Dict, Any, Union | ||
|
|
||
| # API Stub for CMM | ||
| class AbstractCryptoMaterialsManager(): |
There was a problem hiding this comment.
There was a problem hiding this comment.
thanks, now I know my abc's
| from attrs import define | ||
| from .keyring import AbstractKeyring | ||
| from .materials import EncryptionMaterials, DecryptionMaterials | ||
| from typing import List, Dict, Any, Union |
There was a problem hiding this comment.
You can use the built-int dict and list types now (3.9+)
|
|
||
| # API Stub for CMM | ||
| class AbstractCryptoMaterialsManager: | ||
| def getEncryptionMaterials(self, encMatsRequest): |
There was a problem hiding this comment.
style nit that I'm sure a linter will pick up -- snakecase methods and field names
| def getEncryptionMaterials(self, encMatsRequest): | |
| def get_encryption_materials(self, enc_mats_request): |
| encrypted_data_key (bytes): The encrypted data key | ||
| """ | ||
|
|
||
| key_provider_info: str = field() |
There was a problem hiding this comment.
I think the field()s are redundant on a class annotated with define? Not terribly familiar with this though, and you may have plans to expand the behavior in the field calls here
There was a problem hiding this comment.
that's correct, since none of these has a default, we can remove them
| # There is a newer version, but MPL wants this one. | ||
| cryptography = "^43.0.1" |
There was a problem hiding this comment.
Ok -- given that you don't need the MPL let me also save you from a mistake I made and set this as a range
| # There is a newer version, but MPL wants this one. | |
| cryptography = "^43.0.1" | |
| # There is a newer version, but MPL wants this one. | |
| cryptography = ">=45.0.1, <46" |
the "^43.0.1" syntax resolves to >=43.0.1, <44 which restricts customers.
When launching MPL-Python, we decided the best thing to do was to drop support for as many older versions as possible of cryptography, so ideally we're launching with the newest support possible. It's easy to decrease the minimum version later on but hard to increase it.
| config: S3EncryptionClientConfig = field() | ||
|
|
||
| # TODO: rename Data-> Body to match boto | ||
| def put_object(self, Bucket, Key, Data, EncryptionContext=None, **kwargs): |
There was a problem hiding this comment.
Opening a debate here: I'd suggest just this instead:
| def put_object(self, Bucket, Key, Data, EncryptionContext=None, **kwargs): | |
| def put_object(self, **kwargs): |
imo, our clients' API arguments should align with the boto3 API arguments.
Note that I might expect customers to provide EncryptionContext just in kwargs.
I could be wrong here -- what you have seems totally fine but I think it's worth discussing.
|
|
||
| @define | ||
| class KmsKeyring(S3Keyring): | ||
| kms_client = field() |
There was a problem hiding this comment.
Just a note that I've used botocore.client.BaseClient for the boto3 client typehint before
There was a problem hiding this comment.
ideally it'd be a KmsClient specifically,
but i suppose BaseClient is better than nothing.
There was a problem hiding this comment.
There was a problem hiding this comment.
I think it's actually some default arg shenanigans from line 58 in those logs:
self = KmsKeyring(kms_key_id=<botocore.client.KMS object at 0x7f38961ff5d0>, enable_legacy_wrapping_algorithms='arn:aws:kms:us-west-2:370957321024:alias/S3EC-Python-Github-KMS-Key')
| # Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. | ||
| # SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| import unittest |
There was a problem hiding this comment.
I might suggest pytest instead of unittest:
- more robust feature support
- we have pretty extensive examples of tests using pytest in ESDK and DBESDK doing some complicated things (ex parametrization/matrices, fixtures) so if you ever want more complicated behavior in tests you can just refer to those
| @@ -0,0 +1,656 @@ | |||
| # This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. | |||
There was a problem hiding this comment.
You should gitignore this (and other files)
| # Extract required parameters from kwargs | ||
| bucket = kwargs.pop("Bucket") | ||
| key = kwargs.pop("Key") | ||
| body = kwargs.pop("Body") |
There was a problem hiding this comment.
This implies Body is a required parameter, but boto3 docs imply it is optional: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3/client/put_object.html
Is this intentional?
There was a problem hiding this comment.
Good call, as senseless as it seems, omitting the Body produces a 0 byte object. This is technically fine to do with AES-GCM encryption, so we should support it.
| """Get encryption materials from the keyring. | ||
|
|
||
| Args: | ||
| enc_mats_request (Dict[str, Any]): Request containing encryption parameters |
There was a problem hiding this comment.
| enc_mats_request (Dict[str, Any]): Request containing encryption parameters | |
| enc_mats_request (Dict[str, Any] or EncryptionMaterials): Request containing encryption parameters |
I think this type syntax is still a little off, but you might need to play around with pydocs to find the right syntax
|
|
||
| @define | ||
| class KmsKeyring(S3Keyring): | ||
| kms_client = field() |
There was a problem hiding this comment.
I think it's actually some default arg shenanigans from line 58 in those logs:
self = KmsKeyring(kms_key_id=<botocore.client.KMS object at 0x7f38961ff5d0>, enable_legacy_wrapping_algorithms='arn:aws:kms:us-west-2:370957321024:alias/S3EC-Python-Github-KMS-Key')
| encryption_context_from_request=materials_dict.get( | ||
| "encryption_context_from_request", {} | ||
| ), | ||
| plaintext_data_key=materials_dict.get("PDK"), |
There was a problem hiding this comment.
Why "PDK"? Why not plaintext_data_key? That's more idiomatic
Issue #, if available:
Description of changes:
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.