Skip to content

Update documentation and warnings related to SaveBehavior. #44

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

Merged
merged 6 commits into from
Aug 3, 2018
Merged

Update documentation and warnings related to SaveBehavior. #44

merged 6 commits into from
Aug 3, 2018

Conversation

SalusaSecondus
Copy link
Contributor

This is in support of issue #42

This adds basic documentation to AttributeEncryptor and related example code highlighting the importance of using SaveBehavior.CLOBBER.

All existing tests pass. Some of the existing tests did not properly set this configuration and resulted in proper warnings during the test run:

SEVERE: Use of AttributeEncryptor without SaveBehavior.CLOBBER is an error and may result in data-corruption. This occured while trying to save class com.amazonaws.services.dynamodbv2.testing.types.Mixed

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.*;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad IntelliJ setting injected an import-*. I'll fix this.

Copy link
Contributor

@lizroth lizroth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found a few things we might want to polish up. Let me know your thoughts.

README.md Outdated
@@ -3,6 +3,7 @@
The **[Amazon DynamoDB][ddb] Client-side Encryption in Java** supports encryption and signing of your data when stored in Amazon DynamoDB.

A typical use of this library is when you are using [DynamoDBMapper][ddbmapper], where transparent protection of all objects serialized through the mapper can be enabled via configuring an [AttributeEncryptor][attrencryptor].
**Please note that it is critically important that you use `SaveBehavior.CLOBBER` when using AttributeEncryptor.**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we compact the wording of the warning for grokkability, and add an expanded explanation?

Perhaps:

Important: use SaveBehavior.CLOBBER with AttributeEncryptor. This is because ...

Should https://github.com/aws/aws-dynamodb-encryption-java/blame/ded8364a9baee731f6f83ddddca8cec5bc614f9c/README.md#L77 be DynamoDBMapperConfig.CLOBBER as well? It looks to my quick read like it is affected, since it's using the AttributeEncryptor.


/**
* Encrypts all non-key fields prior to storing them in DynamoDB.
* <em>It is critically important that this is only used with @{link SaveBehavior#CLOBBER}. Use of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Brevity for grokability?:

<em>This must be used with @{link SaveBehavior#CLOBBER}.</em> Use of any other...

Also, I think June would suggest using "can" rather than "may" for clarity, since it is a possibility, not a permission.

}

if (parameters.isPartialUpdate()) {
LOG.error("Use of AttributeEncryptor without SaveBehavior.CLOBBER is an error and may result in data-corruption. " +
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/may/can/?

@@ -58,9 +64,20 @@ public DynamoDBEncryptor getEncryptor() {
public Map<String, AttributeValue> transform(final Parameters<?> parameters) {
// one map of attributeFlags per model class
final ModelClassMetadata metadata = getModelClassMetadata(parameters);

final Map<String, AttributeValue> attributeValues = parameters.getAttributeValues();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a short comment explaining the case being handled here / why this is set to behave this way, for clarity/maintainers?

@@ -58,9 +64,20 @@ public DynamoDBEncryptor getEncryptor() {
public Map<String, AttributeValue> transform(final Parameters<?> parameters) {
// one map of attributeFlags per model class
final ModelClassMetadata metadata = getModelClassMetadata(parameters);

final Map<String, AttributeValue> attributeValues = parameters.getAttributeValues();
if (metadata.doNotTouch) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a behavior change, unless I am missing something. Can we cover it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It isn't a behavior change. In a "DoNotTouch" case, we make no changes whatsoever to the underlying data. I'm just short-circuiting that logic.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK.

@@ -52,6 +52,7 @@ public static void encryptRecord(final String cmkArn, final String region) {
// Encryptor creation
final DynamoDBEncryptor encryptor = DynamoDBEncryptor.getInstance(cmp);
// Mapper Creation
// Please note the use of SaveBehavior.CLOBBER. Omitting this may result in data-corruption.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/may/can/?

@@ -4,6 +4,8 @@ The **[Amazon DynamoDB][ddb] Client-side Encryption in Java** supports encryptio

A typical use of this library is when you are using [DynamoDBMapper][ddbmapper], where transparent protection of all objects serialized through the mapper can be enabled via configuring an [AttributeEncryptor][attrencryptor].

**Important: Use `SaveBehavior.CLOBBER` with `AttributeEncryptor`. If you do not do so you risk corrupting your signatures and encrypted data.**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explain why this is the case?

Copy link
Contributor

@bdonlan bdonlan Aug 3, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important: Use SaveBehavior.CLOBBER with AttributeEncryptor. If you do not do so you risk corrupting your signatures and encrypted data. When CLOBBER is not specified, fields that are present in the record may not be passed down to the encryptor, which results in fields being left out of the record signature. This in turn can result in records failing to decrypt.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 - I want to learn more about why this is the desired behavior

Using CLOBBER basically disables the Optimistic Locking which is a super useful feature provided by DynamoDB. This says we shouldn't use AttributeEncryptor and Optimistic Locking together.

We support partial encryption and signing today, can those fields be updated safely without CLOBBER save?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We will re-visit how optimistic logging works with encrypted data. It definitely will not work without a version field. This change is still important due to the need to warn people about the risk of data-corruption.

// unmodified fields. Thus, upon untransform, the signature verification will fail as it won't cover all
// expected fields.
if (parameters.isPartialUpdate()) {
LOG.error("Use of AttributeEncryptor without SaveBehavior.CLOBBER is an error and can result in data-corruption. " +
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For anyone who is not using CLOBBER today, there will be tons of errors in the log and the operation is not actually failing.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is correct because they are in a dangerous error case and are at risk for data-corruption. Minor software changes outside of their (or our) control could result in this going from a "working due to luck" state to a "broken" state. We consider it sufficiently important to notify people of this dangerous configuration that an ERROR level log is appropriate.

The next minor (non-patch) version will throw an exception in this case. Please see #32

@lizroth lizroth merged commit 4d6b40e into aws:master Aug 3, 2018
seebees pushed a commit that referenced this pull request Dec 12, 2023
Restore logic to set UA suffixes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants