diff --git a/core/src/main/java/org/apache/iceberg/CatalogProperties.java b/core/src/main/java/org/apache/iceberg/CatalogProperties.java index f35c90c4e80c..59744e50924f 100644 --- a/core/src/main/java/org/apache/iceberg/CatalogProperties.java +++ b/core/src/main/java/org/apache/iceberg/CatalogProperties.java @@ -162,5 +162,15 @@ private CatalogProperties() {} public static final long AUTH_SESSION_TIMEOUT_MS_DEFAULT = TimeUnit.HOURS.toMillis(1); public static final String ENCRYPTION_KMS_TYPE = "encryption.kms-type"; + public static final String ENCRYPTION_KMS_TYPE_AWS = "aws"; + public static final String ENCRYPTION_KMS_TYPE_AZURE = "azure"; + public static final String ENCRYPTION_KMS_TYPE_GCP = "gcp"; + public static final String ENCRYPTION_KMS_IMPL = "encryption.kms-impl"; + public static final String ENCRYPTION_KMS_IMPL_AWS = + "org.apache.iceberg.aws.AwsKeyManagementClient"; + public static final String ENCRYPTION_KMS_IMPL_AZURE = + "org.apache.iceberg.azure.keymanagement.AzureKeyManagementClient"; + public static final String ENCRYPTION_KMS_IMPL_GCP = + "org.apache.iceberg.gcp.GcpKeyManagementClient"; } diff --git a/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java b/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java index 1f0461bc4d97..382d244883d6 100644 --- a/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java +++ b/core/src/main/java/org/apache/iceberg/encryption/EncryptionUtil.java @@ -21,6 +21,7 @@ import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; import org.apache.iceberg.CatalogProperties; @@ -53,8 +54,18 @@ public static KeyManagementClient createKmsClient(Map catalogPro kmsType, kmsImpl); - // TODO: Add KMS implementations - Preconditions.checkArgument(kmsType == null, "Unsupported KMS type: %s", kmsType); + if (kmsType != null) { + kmsImpl = + switch (kmsType.toLowerCase(Locale.ROOT)) { + case CatalogProperties.ENCRYPTION_KMS_TYPE_AWS -> + CatalogProperties.ENCRYPTION_KMS_IMPL_AWS; + case CatalogProperties.ENCRYPTION_KMS_TYPE_AZURE -> + CatalogProperties.ENCRYPTION_KMS_IMPL_AZURE; + case CatalogProperties.ENCRYPTION_KMS_TYPE_GCP -> + CatalogProperties.ENCRYPTION_KMS_IMPL_GCP; + default -> throw new IllegalStateException("Unsupported KMS type: " + kmsType); + }; + } KeyManagementClient kmsClient; DynConstructors.Ctor ctor; diff --git a/core/src/test/java/org/apache/iceberg/encryption/TestEncryptionUtil.java b/core/src/test/java/org/apache/iceberg/encryption/TestEncryptionUtil.java index 39f0e7a38153..edb55d321842 100644 --- a/core/src/test/java/org/apache/iceberg/encryption/TestEncryptionUtil.java +++ b/core/src/test/java/org/apache/iceberg/encryption/TestEncryptionUtil.java @@ -19,6 +19,7 @@ package org.apache.iceberg.encryption; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.io.ByteArrayOutputStream; import java.io.File; @@ -27,6 +28,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.Map; import org.apache.iceberg.CatalogProperties; +import org.apache.iceberg.relocated.com.google.common.collect.ImmutableMap; import org.junit.jupiter.api.Test; public class TestEncryptionUtil { @@ -52,6 +54,21 @@ public void testClassLoader() assertThat(kmsClientObj.getClass().getClassLoader()).isSameAs(customClassLoader); } + @Test + public void testInvalidTypeAndImpl() { + assertThatThrownBy( + () -> + EncryptionUtil.createKmsClient( + ImmutableMap.of( + CatalogProperties.ENCRYPTION_KMS_TYPE, + CatalogProperties.ENCRYPTION_KMS_TYPE_AWS, + CatalogProperties.ENCRYPTION_KMS_IMPL, + CatalogProperties.ENCRYPTION_KMS_IMPL_AWS))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage( + "Cannot set both KMS type (aws) and KMS impl (org.apache.iceberg.aws.AwsKeyManagementClient)"); + } + static class UnitTestCustomClassLoader extends ClassLoader { @Override diff --git a/docs/docs/encryption.md b/docs/docs/encryption.md index 5da51486f76b..cbdce85e760e 100644 --- a/docs/docs/encryption.md +++ b/docs/docs/encryption.md @@ -28,7 +28,7 @@ Currently, encryption is supported in the Hive and REST catalogs for tables with Two parameters are required to activate encryption of a table: -1. Catalog property `encryption.kms-impl`, that specifies the class path for a client of a KMS ("key management service"). +1. Catalog property that specifies the KMS ("key management service"). It can be either `encryption.kms-type` for pre-defined KMS clients (`aws`, `azure` or `gcp`) or `encryption.kms-impl` with the client class path for custom KMS clients. 2. Table property `encryption.key-id`, that specifies the ID of a master key used to encrypt and decrypt the table. Master keys are stored and managed in the KMS. For more details on table encryption, see the "Appendix: Internals Overview" [subsection](#appendix-internals-overview). @@ -42,7 +42,7 @@ spark-sql --packages org.apache.iceberg:iceberg-spark-runtime-{{ sparkVersionMaj --conf spark.sql.catalog.spark_catalog.type=hive \ --conf spark.sql.catalog.local=org.apache.iceberg.spark.SparkCatalog \ --conf spark.sql.catalog.local.type=hive \ - --conf spark.sql.catalog.local.encryption.kms-impl=org.apache.iceberg.aws.AwsKeyManagementClient + --conf spark.sql.catalog.local.encryption.kms-type=aws ``` ```sql diff --git a/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java b/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java index a6264c67fd88..93267716db66 100644 --- a/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java +++ b/hive-metastore/src/main/java/org/apache/iceberg/hive/HiveCatalog.java @@ -126,7 +126,8 @@ public void initialize(String inputName, Map properties) { ? new HadoopFileIO(conf) : CatalogUtil.loadFileIO(fileIOImpl, properties, conf); - if (catalogProperties.containsKey(CatalogProperties.ENCRYPTION_KMS_IMPL)) { + if (catalogProperties.containsKey(CatalogProperties.ENCRYPTION_KMS_TYPE) + || catalogProperties.containsKey(CatalogProperties.ENCRYPTION_KMS_IMPL)) { this.keyManagementClient = EncryptionUtil.createKmsClient(properties); }