Skip to content

Commit 311dbbb

Browse files
authored
AWS: Support S3 DSSE-KMS encryption (apache#8370)
1 parent d4c2ef8 commit 311dbbb

File tree

5 files changed

+53
-5
lines changed

5 files changed

+53
-5
lines changed

aws/src/integration/java/org/apache/iceberg/aws/s3/TestS3FileIOIntegration.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,21 @@ public void testServerSideKmsEncryptionWithDefaultKey() throws Exception {
291291
aliasListEntry -> assertThat(aliasListEntry.aliasName()).isEqualTo("alias/aws/s3"));
292292
}
293293

294+
@Test
295+
public void testDualLayerServerSideKmsEncryption() throws Exception {
296+
S3FileIOProperties properties = new S3FileIOProperties();
297+
properties.setSseType(S3FileIOProperties.DSSE_TYPE_KMS);
298+
properties.setSseKey(kmsKeyArn);
299+
S3FileIO s3FileIO = new S3FileIO(clientFactory::s3, properties);
300+
write(s3FileIO);
301+
validateRead(s3FileIO);
302+
GetObjectResponse response =
303+
s3.getObject(GetObjectRequest.builder().bucket(bucketName).key(objectKey).build())
304+
.response();
305+
assertThat(response.serverSideEncryption()).isEqualTo(ServerSideEncryption.AWS_KMS_DSSE);
306+
assertThat(response.ssekmsKeyId()).isEqualTo(kmsKeyArn);
307+
}
308+
294309
@Test
295310
public void testServerSideCustomEncryption() throws Exception {
296311
// generate key

aws/src/main/java/org/apache/iceberg/aws/s3/S3FileIOProperties.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ public class S3FileIOProperties implements Serializable {
9292
*/
9393
public static final String SSE_TYPE_KMS = "kms";
9494

95+
/**
96+
* S3 DSSE-KMS encryption.
97+
*
98+
* <p>For more details:
99+
* https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingDSSEncryption.html
100+
*/
101+
public static final String DSSE_TYPE_KMS = "dsse-kms";
102+
95103
/**
96104
* S3 SSE-S3 encryption.
97105
*
@@ -109,9 +117,9 @@ public class S3FileIOProperties implements Serializable {
109117
public static final String SSE_TYPE_CUSTOM = "custom";
110118

111119
/**
112-
* If S3 encryption type is SSE-KMS, input is a KMS Key ID or ARN. In case this property is not
113-
* set, default key "aws/s3" is used. If encryption type is SSE-C, input is a custom base-64
114-
* AES256 symmetric key.
120+
* If S3 encryption type is SSE-KMS or DSSE-KMS, input is a KMS Key ID or ARN. In case this
121+
* property is not set, default key "aws/s3" is used. If encryption type is SSE-C, input is a
122+
* custom base-64 AES256 symmetric key.
115123
*/
116124
public static final String SSE_KEY = "s3.sse.key";
117125

aws/src/main/java/org/apache/iceberg/aws/s3/S3RequestUtil.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ static void configureEncryption(
111111
kmsKeySetter.apply(s3FileIOProperties.sseKey());
112112
break;
113113

114+
case S3FileIOProperties.DSSE_TYPE_KMS:
115+
encryptionSetter.apply(ServerSideEncryption.AWS_KMS_DSSE);
116+
kmsKeySetter.apply(s3FileIOProperties.sseKey());
117+
break;
118+
114119
case S3FileIOProperties.SSE_TYPE_S3:
115120
encryptionSetter.apply(ServerSideEncryption.AES256);
116121
break;

aws/src/test/java/org/apache/iceberg/aws/s3/TestS3RequestUtil.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,25 @@ public void testConfigureServerSideKmsEncryption() {
8888
Assertions.assertThat(customMd5).isNull();
8989
}
9090

91+
@Test
92+
public void testConfigureDualLayerServerSideKmsEncryption() {
93+
S3FileIOProperties s3FileIOProperties = new S3FileIOProperties();
94+
s3FileIOProperties.setSseType(S3FileIOProperties.DSSE_TYPE_KMS);
95+
s3FileIOProperties.setSseKey("key");
96+
S3RequestUtil.configureEncryption(
97+
s3FileIOProperties,
98+
this::setServerSideEncryption,
99+
this::setKmsKeyId,
100+
this::setCustomAlgorithm,
101+
this::setCustomKey,
102+
this::setCustomMd5);
103+
Assertions.assertThat(serverSideEncryption).isEqualTo(ServerSideEncryption.AWS_KMS_DSSE);
104+
Assertions.assertThat(kmsKeyId).isEqualTo("key");
105+
Assertions.assertThat(customAlgorithm).isNull();
106+
Assertions.assertThat(customKey).isNull();
107+
Assertions.assertThat(customMd5).isNull();
108+
}
109+
91110
@Test
92111
public void testConfigureEncryptionSkipNullSetters() {
93112
S3FileIOProperties s3FileIOProperties = new S3FileIOProperties();

docs/docs/aws.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,15 @@ Here are the configurations that users can tune related to this feature:
319319

320320
* [SSE-S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html): When you use Server-Side Encryption with Amazon S3-Managed Keys (SSE-S3), each object is encrypted with a unique key. As an additional safeguard, it encrypts the key itself with a master key that it regularly rotates. Amazon S3 server-side encryption uses one of the strongest block ciphers available, 256-bit Advanced Encryption Standard (AES-256), to encrypt your data.
321321
* [SSE-KMS](https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html): Server-Side Encryption with Customer Master Keys (CMKs) Stored in AWS Key Management Service (SSE-KMS) is similar to SSE-S3, but with some additional benefits and charges for using this service. There are separate permissions for the use of a CMK that provides added protection against unauthorized access of your objects in Amazon S3. SSE-KMS also provides you with an audit trail that shows when your CMK was used and by whom. Additionally, you can create and manage customer managed CMKs or use AWS managed CMKs that are unique to you, your service, and your Region.
322+
* [DSSE-KMS](https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingDSSEncryption.html): Dual-layer Server-Side Encryption with AWS Key Management Service keys (DSSE-KMS) is similar to SSE-KMS, but applies two layers of encryption to objects when they are uploaded to Amazon S3. DSSE-KMS can be used to fulfill compliance standards that require you to apply multilayer encryption to your data and have full control of your encryption keys.
322323
* [SSE-C](https://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html): With Server-Side Encryption with Customer-Provided Keys (SSE-C), you manage the encryption keys and Amazon S3 manages the encryption, as it writes to disks, and decryption when you access your objects.
323324

324325
To enable server side encryption, use the following configuration properties:
325326

326327
| Property | Default | Description |
327328
| --------------------------------- | ---------------------------------------- | ------------------------------------------------------ |
328-
| s3.sse.type | `none` | `none`, `s3`, `kms` or `custom` |
329-
| s3.sse.key | `aws/s3` for `kms` type, null otherwise | A KMS Key ID or ARN for `kms` type, or a custom base-64 AES256 symmetric key for `custom` type. |
329+
| s3.sse.type | `none` | `none`, `s3`, `kms`, `dsse-kms` or `custom` |
330+
| s3.sse.key | `aws/s3` for `kms` and `dsse-kms` types, null otherwise | A KMS Key ID or ARN for `kms` and `dsse-kms` types, or a custom base-64 AES256 symmetric key for `custom` type. |
330331
| s3.sse.md5 | null | If SSE type is `custom`, this value must be set as the base-64 MD5 digest of the symmetric key to ensure integrity. |
331332

332333
### S3 Access Control List

0 commit comments

Comments
 (0)