Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support transactional methods in EncryptionClient #406

Open
jplock opened this issue Sep 26, 2022 · 2 comments
Open

Support transactional methods in EncryptionClient #406

jplock opened this issue Sep 26, 2022 · 2 comments

Comments

@jplock
Copy link

jplock commented Sep 26, 2022

Problem:

Are not currently supported by the EncryptionClient and passed through to the underlying client.

Solution:

Fully implement transact_get_items() and transact_write_items() in the EncryptionClient

Out of scope:

Is there anything the solution will intentionally NOT address? No

Workaround

I was able to implement the following workaround to encrypt one of the Put requests within my transaction:

aws_kms_cmp = AwsKmsCryptographicMaterialsProvider(key_id=KEY_ARN)
actions = AttributeActions(
    default_action=CryptoAction.DO_NOTHING,
    attribute_actions={"access_token": CryptoAction.ENCRYPT_AND_SIGN},
)
encrypted_client = EncryptedClient(
    client=dynamodb.meta.client,
    materials_provider=aws_kms_cmp,
    attribute_actions=actions,
    expect_standard_dictionaries=True,
    auto_refresh_table_indexes=False
)

item = {
    "pk": f"USER#{user_id}#ITEM#{item_id}",
    "sk": "v0",
    "access_token": access_token,
    "institution_id": institution_id,
    "institution_name": institution.get("name"),
    "link_session_id": metadata.get("link_session_id"),
    "created_at": now,
}

def mock_write_method(**kwargs):
    return kwargs.get("Item")

encrypt_item = partial(
    encrypt_put_item,
    encrypted_client._encrypt_item,
    encrypted_client._item_crypto_config,
    mock_write_method,
)
encrypted_item = encrypt_item(TableName=TABLE_NAME, Item=item)

items = [
    {
        "Put": {
            "TableName": TABLE_NAME,
            "Item": encrypted_item
        }
    }
]
dynamodb_client.transact_write_items(TransactItems=items)
@imabhichow
Copy link
Contributor

Hi @jplock

Thank you for your feature request, and for posting a workaround. You are correct that we currently do not support DDB Transactions in the DynamoDB Encryption Client for Python. I will keep this issue open for any future updates we may have.

In your workaround, one thing that you will need to be careful of is including any UPDATE in your Transact Write. DDB UPDATE can lead to signature verification failures on future reads if you do not include all signed fields in the update. See our documentation here:
https://docs.aws.amazon.com/dynamodb-encryption-client/latest/devguide/troubleshooting.html#change-data-model

@jplock
Copy link
Author

jplock commented Nov 22, 2022

Thanks @imabhichow for the feedback. In my use-case I'm not updating records, always overwriting with a Put.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants