diff --git a/docs/config-definition.md b/docs/config-definition.md
index d1c5a2b7b1..3f11e5d997 100644
--- a/docs/config-definition.md
+++ b/docs/config-definition.md
@@ -1,9 +1,9 @@
# Ark Config definition
-* [Overview][10]
-* [Example][11]
-* [Parameter Reference][8]
- * [Main config][9]
+* [Overview][11]
+* [Example][12]
+* [Parameter Reference][9]
+ * [Main config][10]
* [AWS][0]
* [GCP][1]
* [Azure][2]
@@ -70,17 +70,18 @@ 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
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"
Specify an [AWS KMS key][5] id to enable encryption of the backups stored in S3. Only works with AWS S3 and may require explicitly granting key usage rights.|
### GCP
| Key | Type | Default | Meaning |
| --- | --- | --- | --- |
-| `project` | string | Required Field | *Example*: "project-example-3jsn23"
See the [Project ID documentation][5] for details. |
-| `zone` | string | Required Field | *Example*: "us-central1-a"
See [GCP documentation][6] for the full list. |
+| `project` | string | Required Field | *Example*: "project-example-3jsn23"
See the [Project ID documentation][6] for details. |
+| `zone` | string | Required Field | *Example*: "us-central1-a"
See [GCP documentation][7] for the full list. |
### Azure
| Key | Type | Default | Meaning |
| --- | --- | --- | --- |
-| `location` | string | Required Field | *Example*: "Canada East"
See [the list of available locations][7] (note that this particular page refers to them as "Regions"). |
+| `location` | string | Required Field | *Example*: "Canada East"
See [the list of available locations][8] (note that this particular page refers to them as "Regions"). |
| `apiTimeout` | metav1.Duration | 1m0s | How long to wait for an API Azure request to complete before timeout. |
[0]: #aws
@@ -88,10 +89,11 @@ The configurable parameters are as follows:
[2]: #azure
[3]: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-available-regions
[4]: http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html#concepts-availability-zones
-[5]: https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects
-[6]: https://cloud.google.com/compute/docs/regions-zones/regions-zones
-[7]: https://azure.microsoft.com/en-us/regions/
-[8]: #parameter-reference
-[9]: #main-config-parameters
-[10]: #overview
-[11]: #example
+[5]: http://docs.aws.amazon.com/kms/latest/developerguide/overview.html
+[6]: https://cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects
+[7]: https://cloud.google.com/compute/docs/regions-zones/regions-zones
+[8]: https://azure.microsoft.com/en-us/regions/
+[9]: #parameter-reference
+[10]: #main-config-parameters
+[11]: #overview
+[12]: #example
diff --git a/pkg/apis/ark/v1/config.go b/pkg/apis/ark/v1/config.go
index 6f66bc3c35..60399f4c12 100644
--- a/pkg/apis/ark/v1/config.go
+++ b/pkg/apis/ark/v1/config.go
@@ -98,6 +98,7 @@ type AWSConfig struct {
DisableSSL bool `json:"disableSSL"`
S3ForcePathStyle bool `json:"s3ForcePathStyle"`
S3Url string `json:"s3Url"`
+ KMSKeyID string `json:"kmsKeyId"`
}
// GCPConfig is configuration information for connecting to GCP.
diff --git a/pkg/cloudprovider/aws/object_storage_adapter.go b/pkg/cloudprovider/aws/object_storage_adapter.go
index 3f293db2ba..8604de3dab 100644
--- a/pkg/cloudprovider/aws/object_storage_adapter.go
+++ b/pkg/cloudprovider/aws/object_storage_adapter.go
@@ -27,16 +27,25 @@ import (
var _ cloudprovider.ObjectStorageAdapter = &objectStorageAdapter{}
type objectStorageAdapter struct {
- s3 *s3.S3
+ s3 *s3.S3
+ kmsKeyID string
}
func (op *objectStorageAdapter) PutObject(bucket string, key string, body io.ReadSeeker) error {
+
req := &s3.PutObjectInput{
Bucket: &bucket,
Key: &key,
Body: body,
}
+ // if kmsKeyID is not empty, enable "aws:kms" encryption and amend the key ID
+ if op.kmsKeyID != "" {
+ sseType := "aws:kms"
+ req.ServerSideEncryption = &sseType
+ req.SSEKMSKeyId = &op.kmsKeyID
+ }
+
_, err := op.s3.PutObject(req)
return err
diff --git a/pkg/cloudprovider/aws/storage_adapter.go b/pkg/cloudprovider/aws/storage_adapter.go
index ee4a46445d..199a63fc99 100644
--- a/pkg/cloudprovider/aws/storage_adapter.go
+++ b/pkg/cloudprovider/aws/storage_adapter.go
@@ -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) {
sess, err := session.NewSession(config)
if err != nil {
return nil, err
@@ -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,
},
}, nil
}
diff --git a/pkg/cmd/server/server.go b/pkg/cmd/server/server.go
index 12b2780e82..1d1a2044b7 100644
--- a/pkg/cmd/server/server.go
+++ b/pkg/cmd/server/server.go
@@ -324,7 +324,7 @@ func getAWSCloudProvider(cloudConfig api.CloudProviderConfig) (cloudprovider.Sto
)
}
- return arkaws.NewStorageAdapter(awsConfig, cloudConfig.AWS.AvailabilityZone)
+ return arkaws.NewStorageAdapter(awsConfig, cloudConfig.AWS.AvailabilityZone, cloudConfig.AWS.KMSKeyID)
}
func getGCPCloudProvider(cloudConfig api.CloudProviderConfig) (cloudprovider.StorageAdapter, error) {