diff --git a/src/applications/files/engine/PhabricatorS3FileStorageEngine.php b/src/applications/files/engine/PhabricatorS3FileStorageEngine.php --- a/src/applications/files/engine/PhabricatorS3FileStorageEngine.php +++ b/src/applications/files/engine/PhabricatorS3FileStorageEngine.php @@ -72,7 +72,9 @@ $data, $this->getBucketName(), $name, - $acl = 'private'); + $acl = 'private', + $serverSideEncryption = $this->getServerSideEncryption(), + $requestHeaders = $this->getRequestHeaders()); $profiler->endServiceCall($call_id, array()); return $name; @@ -144,6 +146,45 @@ } /** + * Retrieve the desired encryption method for objects stored on S3. + * + * @task internal + */ + private function getServerSideEncryption() { + return PhabricatorEnv::getEnvConfigIfExists( + 'storage.s3.serverSideEncryption', ''); + } + + /** + * Set any request headers as needed. + * + * @task internal + */ + private function getRequestHeaders() { + $headers = array(); + + $aws_kms_key_id = PhabricatorEnv::getEnvConfig( + 'storage.s3.serverSideEncryption.aws-kms-key-id'); + if ($this->getServerSideEncryption() == 'aws:kms' && $aws_kms_key_id) { + $headers[] = array('x-amz-server-side-encryption-aws-kms-key-id' => $aws_kms_key_id); + } + + $cust_algo = PhabricatorEnv::getEnvConfig( + 'storage.s3.serverSideEncryption.customer.algorithm'); + $cust_key = PhabricatorEnv::getEnvConfig( + 'storage.s3.serverSideEncryption.customer.key'); + if ($cust_algo && $cust_key) { + $headers[] = array( + 'x-amz-server-side-encryption-customer-algorithm' => $cust_algo, + 'x-amz-server-side-encryption-customer-key' => base64_encode($cust_key), + 'x-amz-server-side-encryption-customer-key-MD5' => base64_encode(md5($cust_key)), + ); + } + + return $headers; + } + + /** * Create a new S3 API object. * * @task internal diff --git a/src/docs/user/configuration/configuring_file_storage.diviner b/src/docs/user/configuration/configuring_file_storage.diviner --- a/src/docs/user/configuration/configuring_file_storage.diviner +++ b/src/docs/user/configuration/configuring_file_storage.diviner @@ -166,6 +166,26 @@ - `amazon-s3.secret-key`: Your AWS secret key. - `storage.s3.bucket`: S3 bucket name where files should be stored. +Optionally, you may also configure the use of one of S3's three types of +server-side encryption (SSE-S3, SSE-KMS, SSE-C). See +[[ https://docs.aws.amazon.com/AmazonS3/latest/dev/serv-side-encryption.html | +S3's SSE documention ]] for more information and the values you may +wish to use for the following keys: + + - `storage.s3.serverSideEncryption`: The value to send in the + `x-amz-server-side-encryption` header (e.g., 'AES256' or 'aws:kms'). + + - `storage.s3.serverSideEncryption.aws-kms-key-id`: The value to send in the + `x-amz-server-side-encryption-aws-kms-key-id` header. + + - `storage.s3.serverSideEncryption.customer.algorithm`: The value to send in + the `x-amz-server-side-encryption-customer-algorithm` header (e.g., + 'AES256'). + + - `storage.s3.serverSideEncryption.customer.key`: The value to send in the + `x-amz-server-side-encryption-customer-key` header. Note that this will be + encoded as base64 when sending. + Testing Storage Engines =======================