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

Add support for S3 SSE with KMS #29

Merged
merged 1 commit into from
Aug 14, 2017

Conversation

madddi
Copy link
Contributor

@madddi madddi commented Aug 10, 2017

Issue #24

If not specified in the configuration, kmsKeyID should be an empty string, which gets passed to PutObjectInput. Because an empty string is essentially undefined and the AWS SDK checks if a key ID is given, I did not add checks on our side.

@heptibot
Copy link

Can one of the admins verify this patch?

@ncdc
Copy link
Contributor

ncdc commented Aug 10, 2017

ok to test

Copy link
Contributor

@ncdc ncdc left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

Body: body,
Bucket: &bucket,
Key: &key,
SSEKMSKeyId: &op.KMSKeyID,
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we also need this for the other actions?

Copy link
Contributor Author

@madddi madddi Aug 10, 2017

Choose a reason for hiding this comment

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

I find the docs unclear regarding GetObjectInput with KMS. Deleting and listing objects is definitely possible without the key. I compared the code with the Docker registries implementation and usage of GetObject and it seems that s3.GetObject does "the right thing" if it tries to get an encrypted object without explicitly specifying the key ID.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, we'll try it out and see how it works both with "" for the key and with a real one.

@@ -70,6 +70,7 @@ The configurable parameters are as follows:
| `disableSSL` | bool | `false` | Set this to `true` if you are using Minio (or another local, S3-compatible storage service) and your deployment is not secured. |
| `s3ForcePathStyle` | bool | `false` | Set this to `true` if you are using a local storage service like Minio. |
| `s3Url` | string | Required field for non-AWS-hosted storage| *Example*: http://minio:9000<br><br>You can specify the AWS S3 URL here for explicitness, but Ark can already generate it from `region`, `availabilityZone`, and `bucket`. This field is primarily for local sotrage services like Minio.|
| `kmsKeyID` | string | Empty | *Example*: "502b409c-4da1-419f-a16e-eif453b3i49f"<br><br>Specify an AWS KMS key id to enable encryption of the backups stored in S3. Only works with AWS S3 and may require explicitly granting key usage rights. |
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove blank space in between . and |?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@@ -70,6 +70,7 @@ The configurable parameters are as follows:
| `disableSSL` | bool | `false` | Set this to `true` if you are using Minio (or another local, S3-compatible storage service) and your deployment is not secured. |
| `s3ForcePathStyle` | bool | `false` | Set this to `true` if you are using a local storage service like Minio. |
| `s3Url` | string | Required field for non-AWS-hosted storage| *Example*: http://minio:9000<br><br>You can specify the AWS S3 URL here for explicitness, but Ark can already generate it from `region`, `availabilityZone`, and `bucket`. This field is primarily for local sotrage services like Minio.|
| `kmsKeyID` | string | Empty | *Example*: "502b409c-4da1-419f-a16e-eif453b3i49f"<br><br>Specify an AWS KMS key id to enable encryption of the backups stored in S3. Only works with AWS S3 and may require explicitly granting key usage rights.|
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: link "AWS KMS key" to http://docs.aws.amazon.com/kms/latest/developerguide/overview.html for convenience?

Copy link
Contributor

Choose a reason for hiding this comment

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

other than this LGTM!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea 🙂

@mattmoyer mattmoyer self-assigned this Aug 11, 2017
Copy link
Contributor

@mattmoyer mattmoyer left a comment

Choose a reason for hiding this comment

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

@madddi thanks for this!

It's not quite working yet, but I think I see why (commented inline above). This is the error I am getting:

I0811 15:59:22.620810       1 backup_controller.go:263] backup heptio-ark/test5 failed: InvalidArgument: Server Side Encryption with AWS KMS managed key requires HTTP header x-amz-server-side-encryption : aws:kms
	status code: 400, request id: 2D8DF113E54DD682

Body: body,
Bucket: &bucket,
Key: &key,
SSEKMSKeyId: &op.KMSKeyID,
Copy link
Contributor

Choose a reason for hiding this comment

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

This also needs ServerSideEncryption: "aws:kms" if op.KMSKeyID != "".

Copy link
Contributor

Choose a reason for hiding this comment

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

Given that we need to set ServerSideEncryption based on the presence of kmsKeyID, let's only set ServerSideEncryption and SSEKMSKeyId if necessary.

@@ -27,14 +27,16 @@ import (
var _ cloudprovider.ObjectStorageAdapter = &objectStorageAdapter{}

type objectStorageAdapter struct {
s3 *s3.S3
s3 *s3.S3
KMSKeyID string
Copy link
Contributor

Choose a reason for hiding this comment

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

Very minor nit, but this should probably be package-local kmsKeyID rather than KMSKeyID.

@madddi madddi force-pushed the feature/s3-ss3-kms-support branch 2 times, most recently from 7b6ec6e to 9e66aa0 Compare August 11, 2017 18:40
Copy link
Contributor

@mattmoyer mattmoyer left a comment

Choose a reason for hiding this comment

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

Works great for me now. I had a couple of comments but I'm also +1 as-is.

$ aws s3api head-object --bucket moyer-dev-ark --key test/test.tar.gz
{
    "AcceptRanges": "bytes",
    "ContentType": "binary/octet-stream",
    "LastModified": "Fri, 11 Aug 2017 20:37:49 GMT",
    "ContentLength": 54752,
    "ETag": "\"a8ec4baa50e668fc0cbe15fedc452873\"",
    "ServerSideEncryption": "aws:kms",
    "SSEKMSKeyId": "arn:aws:kms:us-east-2:835338462208:key/18a72e1f-6e67-4c2a-98d6-c81a4c0612b2",
    "Metadata": {}
}

// if kmsKeyID is not empty, enable "aws:kms" encryption and amend the key ID
if op.kmsKeyID != "" {
sseType := "aws:kms"
req.ServerSideEncryption = &sseType
Copy link
Contributor

Choose a reason for hiding this comment

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

Small nit if you're interested, aws-sdk-go has a helper for this req.ServerSideEncryption = aws.String("aws:kms"). I have no idea why the API is this way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, good to know. Assigning the string a variable just for the pointer was ugly.

@@ -98,6 +98,7 @@ type AWSConfig struct {
DisableSSL bool `json:"disableSSL"`
S3ForcePathStyle bool `json:"s3ForcePathStyle"`
S3Url string `json:"s3Url"`
KMSKeyID string `json:"kmsKeyId"`
Copy link
Contributor

Choose a reason for hiding this comment

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

I got tripped up on this being kmsKeyId and not kmsKeyID. It looks like we're inconsistent in other keys (s3Url rather than s3URL but disableSSL, not disableSsl). @ncdc thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

It's possible some of the discrepancies are from me manually generating some tags vs using vim-go's :GoAddTags - can't say for sure. Consistency would be nice... But not something we need to change right now. Especially since it breaks backwards compat.

@@ -1,9 +1,9 @@
# Ark Config definition

* [Overview][10]
Copy link
Contributor

Choose a reason for hiding this comment

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

@abiogenesis-now I thought you said we didn't have to renumber everything?

Copy link
Contributor

Choose a reason for hiding this comment

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

We don't >< I think the numbers might make it confusing (because people assume that it needs to be in order when it doesn't, @madddi could just append the new link to the end of the numbered list). Essentially the stuff at the bottom are K/V pairs (shorthands and their links), which are most useful when you are reusing the same link multiple times throughout a doc.

This is probably fine as is but let me know if you think we should add some sort of note about this to Contributing or something @ncdc

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd prefer to keep the changes to a minimum, and just append the new link. Would you mind doing that @madddi? Sorry for the confusion!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I already knew I could just append the new link but thought it'd be nicer if the order of the links and the numbers would match. I'll change it, no problem.

}

func (op *objectStorageAdapter) PutObject(bucket string, key string, body io.ReadSeeker) error {

Copy link
Contributor

Choose a reason for hiding this comment

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

Remove blank line

req := &s3.PutObjectInput{
Bucket: &bucket,
Key: &key,
Body: body,
}

// if kmsKeyID is not empty, enable "aws:kms" encryption and amend the key ID
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure "amend" is the correct word. Maybe just end the comment at "encryption"?

@@ -32,7 +32,7 @@ type storageAdapter struct {

var _ cloudprovider.StorageAdapter = &storageAdapter{}

func NewStorageAdapter(config *aws.Config, availabilityZone string) (cloudprovider.StorageAdapter, error) {
func NewStorageAdapter(config *aws.Config, availabilityZone string, KMSKeyID string) (cloudprovider.StorageAdapter, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

s/KMSKeyID/kmsKeyID/

@@ -48,7 +48,8 @@ func NewStorageAdapter(config *aws.Config, availabilityZone string) (cloudprovid
az: availabilityZone,
},
objectStorage: &objectStorageAdapter{
s3: s3.New(sess),
s3: s3.New(sess),
kmsKeyID: KMSKeyID,
Copy link
Contributor

Choose a reason for hiding this comment

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

s/KMSKeyID/kmsKeyID/

Signed-off-by: Mathias Merscher <Mathias.Merscher@dg-i.net>
@ncdc
Copy link
Contributor

ncdc commented Aug 14, 2017

@abiogenesis-now @mattmoyer any other comments?

@jesscodez
Copy link
Contributor

LGTM -- @ncdc do you think this encryption feature is worth mentioning in the last bullet point of cloud-provider-specifics.md? I'm ok either way, but I've noticed that people tend to read that document more.

@ncdc
Copy link
Contributor

ncdc commented Aug 14, 2017

@abiogenesis-now we can do it in a follow-up if needed

@ncdc ncdc added this to the v0.4.0 milestone Aug 14, 2017
@ncdc ncdc merged commit 41e7861 into vmware-tanzu:master Aug 14, 2017
@ncdc
Copy link
Contributor

ncdc commented Aug 14, 2017

Thanks again @madddi!!!

@madddi madddi deleted the feature/s3-ss3-kms-support branch July 19, 2018 16:13
jmontleon added a commit to jmontleon/velero that referenced this pull request Aug 26, 2019
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.

5 participants