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

feat: S3 server-side encryption #5402

Merged
merged 6 commits into from
Feb 26, 2024
Merged

Conversation

wjones127
Copy link
Member

Which issue does this PR close?

Closes #5087.

Rationale for this change

What changes are included in this PR?

Adds support for SSE-KMS and DSSE-KMS encryption with Amazon S3. SSE-C (user-provided keys) is left for a future PR.

Users can configure these with the environment variables / config values aws_server_side_encryption, aws_sse_kms_key_id, aws_sse_bucket_key_enabled. I chose these since they seem to parallel the available settings in AWS CLI.

In addition there are with_sse_kms_encryption() and with_dsse_kms_encryption() methods on the builder.

Are there any user-facing changes?

Adds new APIs.

@wjones127 wjones127 added the object-store Object Store Interface label Feb 15, 2024
Comment on lines 75 to 91
#### Encryption tests

To run integration tests with encryption, you can set the following environment variables:

```
export AWS_SERVER_SIDE_ENCRYPTION=aws:kms
export AWS_SSE_KMS_KEY_ID=<some-key-id>
export AWS_SSE_BUCKET_KEY=false
```

As well as:

```
unset AWS_SSE_BUCKET_KEY
export AWS_SERVER_SIDE_ENCRYPTION=aws:kms:dsse
export AWS_SSE_KMS_KEY_ID=<some-key-id>
```
Copy link
Member Author

Choose a reason for hiding this comment

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

✅ I have manually run the encryption tests against AWS S3.

Copy link
Member Author

@wjones127 wjones127 left a comment

Choose a reason for hiding this comment

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

✅ I've also checked the encryption tests against localstack.

@wjones127 wjones127 marked this pull request as ready for review February 15, 2024 21:20
@wjones127 wjones127 changed the title feat: s3 server-side encryption feat: S3 server-side encryption Feb 15, 2024
@wjones127 wjones127 requested a review from tustvold February 15, 2024 21:20
Copy link
Contributor

@tustvold tustvold left a comment

Choose a reason for hiding this comment

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

Sorry for the delay, I'm currently on holiday. I took a brief look and will take a more thorough look on my return in 2 weeks unless someone else gets there first

object_store/src/aws/builder.rs Outdated Show resolved Hide resolved
@@ -523,7 +535,7 @@ impl S3Client {
let part = (part_idx + 1).to_string();

let response = self
.put_request(path, data)
.put_request(path, data, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

This doesn't appear to match the docs https://docs.aws.amazon.com/AmazonS3/latest/API/API_CreateMultipartUpload.html which would suggest PutPart must include the same headers

Copy link
Member Author

Choose a reason for hiding this comment

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

You are right that CreateMultipartUpload requires the headers, but UploadPart does not accept KMS headers. I actually hit a 400 error from S3 when I was passing them earlier. If you look at the the headers for UploadPart, you'll notice the encryption headers it accepts are only the SSE-C ones, not the KMS ones.

let mut headers = HeaderMap::new();
headers.insert(
"x-amz-server-side-encryption",
HeaderValue::from_static(encryption_type.into()),
Copy link
Member

Choose a reason for hiding this comment

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

HeaderValue has an API called set_sensitive. We can adopt this to prevent accidental leakage of our header value.

Copy link
Member Author

Choose a reason for hiding this comment

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

Okay. Given that, we can just derive Debug for S3EncryptionHeaders. I've made a note that for SSE-C we should use set_sensitive. The current headers are not sensitive.

);
}
if let Some(bucket_key_enabled) = bucket_key_enabled {
headers.insert(
Copy link
Member

Choose a reason for hiding this comment

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

Maybe we can only insert this key while bucket_key_enabled is true? This can save one extra long header.

Copy link
Member Author

Choose a reason for hiding this comment

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

Setting it to false and not setting it at all have different meanings. If you don't set it, then it uses the default setting at the bucket level. But if you set it to false for the specific object, then it will definitely not use bucket key for that particular object. But most of the time, I don't think people will set this header, so it won't be added.

@wjones127
Copy link
Member Author

Sorry for the delay, I'm currently on holiday. I took a brief look and will take a more thorough look on my return in 2 weeks unless someone else gets there first

Good to know. I hope you have a good holiday. Feel free to ignore this PR then. 😄

@wjones127 wjones127 requested a review from Xuanwo February 20, 2024 19:08
Copy link
Contributor

@tustvold tustvold left a comment

Choose a reason for hiding this comment

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

This looks good to me, thank you

@tustvold tustvold merged commit 48fbb29 into apache:master Feb 26, 2024
31 checks passed
@wjones127 wjones127 deleted the s3-encryption branch February 26, 2024 15:47
monkwire pushed a commit to monkwire/arrow-rs that referenced this pull request Feb 27, 2024
* feat: s3 server-side encryption

* cleanup

* fix instructions

* also run with encryption in CI

* feedback

* fix clippy
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
object-store Object Store Interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Can I use S3 server side encryption
3 participants