EnterpriseDB / barman

Barman - Backup and Recovery Manager for PostgreSQL
https://www.pgbarman.org/
GNU General Public License v3.0
2.14k stars 193 forks source link

Support for AWS S3 SSE-C ("SSE Customer Keys") #973

Open AlbinoDrought opened 3 months ago

AlbinoDrought commented 3 months ago

boto3 supports SSE-C: https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/s3.html#uploading-downloading-files-using-sse-customer-keys

I don't believe all of these properties can currently be set in barman. Here's where other SSE properties are set: https://github.com/EnterpriseDB/barman/blob/aaff0600465e0c44192a6453aa76cb8942dfef2b/barman/cloud_providers/aws_s3.py#L175

Unfortunately, I'm not familiar with barman or Python. I imagine something like this:

diff --git a/barman/cloud_providers/aws_s3.py b/barman/cloud_providers/aws_s3.py
index 2e09608..d37888a 100644
--- a/barman/cloud_providers/aws_s3.py
+++ b/barman/cloud_providers/aws_s3.py
@@ -108,6 +108,7 @@ class S3CloudInterface(CloudInterface):
         delete_batch_size=None,
         read_timeout=None,
         sse_kms_key_id=None,
+        sse_customer_key=None,
     ):
         """
         Create a new S3 interface given the S3 destination url and the profile
@@ -126,6 +127,8 @@ class S3CloudInterface(CloudInterface):
           raised when waiting to read from a connection
         :param str|None sse_kms_key_id: the AWS KMS key ID that should be used
           for encrypting uploaded data in S3
+        :param str|None sse_customer_key: the AWS SSE Customer Key (SSE-C) that
+          should be used for encrypting uploaded data in S3
         """
         super(S3CloudInterface, self).__init__(
             url=url,
@@ -138,6 +141,7 @@ class S3CloudInterface(CloudInterface):
         self.endpoint_url = endpoint_url
         self.read_timeout = read_timeout
         self.sse_kms_key_id = sse_kms_key_id
+        self.sse_customer_key = sse_customer_key

         # Extract information from the destination URL
         parsed_url = urlparse(url)
@@ -176,6 +180,9 @@ class S3CloudInterface(CloudInterface):
             additional_args["ServerSideEncryption"] = self.encryption
         if self.sse_kms_key_id:
             additional_args["SSEKMSKeyId"] = self.sse_kms_key_id
+        if self.sse_customer_key:
+            additional_args["SSECustomerKey"] = self.sse_customer_key
+            additional_args["SSECustomerAlgorithm"] = "AES256"
         return additional_args

     def test_connectivity(self):

but my usage of barman also includes retrieving backups (barman-cloud-restore, etc) and I'm not sure where the key would be configured for those.

tonobo commented 1 month ago

:+1:

I'd like to see something like this in cnpg

rdegez commented 1 month ago

Indeed that would be very nice and that's a requirement if you use any object-storage provider that don't support SSE-S3 and still need encryption at rest for CNPG backups and WALs.