Skip to content

Commit 92b056f

Browse files
Adds an abstraction layer to hide the underlying usage of Microsoft Data Encryption(MDE) library (Azure#26878)
* Wrapping AAP EncryptionKeyStoreProvider into Cosmos EncryptionKeyWrapProvider * fixing build error on benchmark project * resolving comments * adding module-info for encryption * build fix * resolving api review comments * fixing benchmark build error * Renamed package to com.azure.encryption.cosmos to fix package resolution * Fixed samples link * build error * resolving import ordering comment Co-authored-by: Kushagra Thapar <kuthapar@microsoft.com>
1 parent 06d51bf commit 92b056f

File tree

57 files changed

+843
-386
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+843
-386
lines changed

eng/code-quality-reports/src/main/resources/spotbugs/spotbugs-exclude.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2075,13 +2075,13 @@
20752075
</Match>
20762076

20772077
<Match>
2078-
<Class name="com.azure.cosmos.encryption.implementation.EncryptionProcessor"/>
2078+
<Class name="com.azure.encryption.cosmos.implementation.EncryptionProcessor"/>
20792079
<Method name="decryptAndSerializeProperty"/>
20802080
<Bug pattern="BC_UNCONFIRMED_CAST"/>
20812081
</Match>
20822082

20832083
<Match>
2084-
<Class name="com.azure.cosmos.encryption.implementation.EncryptionProcessor"/>
2084+
<Class name="com.azure.encryption.cosmos.implementation.EncryptionProcessor"/>
20852085
<Method name="encryptAndSerializeProperty"/>
20862086
<Bug pattern="BC_UNCONFIRMED_CAST"/>
20872087
</Match>

sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/encryption/AsyncEncryptionBenchmark.java

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,12 @@
1616
import com.azure.cosmos.benchmark.BenchmarkHelper;
1717
import com.azure.cosmos.benchmark.Configuration;
1818
import com.azure.cosmos.benchmark.PojoizedJson;
19-
import com.azure.cosmos.encryption.CosmosEncryptionAsyncClient;
20-
import com.azure.cosmos.encryption.CosmosEncryptionAsyncContainer;
21-
import com.azure.cosmos.encryption.CosmosEncryptionAsyncDatabase;
22-
import com.azure.cosmos.encryption.models.CosmosEncryptionAlgorithm;
23-
import com.azure.cosmos.encryption.models.CosmosEncryptionType;
19+
import com.azure.encryption.cosmos.CosmosEncryptionAsyncClient;
20+
import com.azure.encryption.cosmos.CosmosEncryptionAsyncContainer;
21+
import com.azure.encryption.cosmos.CosmosEncryptionAsyncDatabase;
22+
import com.azure.encryption.cosmos.keyprovider.AzureKeyVaultKeyWrapProvider;
23+
import com.azure.encryption.cosmos.models.CosmosEncryptionAlgorithm;
24+
import com.azure.encryption.cosmos.models.CosmosEncryptionType;
2425
import com.azure.cosmos.implementation.HttpConstants;
2526
import com.azure.cosmos.implementation.apachecommons.lang.StringUtils;
2627
import com.azure.cosmos.models.ClientEncryptionIncludedPath;
@@ -46,8 +47,6 @@
4647
import com.codahale.metrics.jvm.CachedThreadStatesGaugeSet;
4748
import com.codahale.metrics.jvm.GarbageCollectorMetricSet;
4849
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
49-
import com.microsoft.data.encryption.AzureKeyVaultKeyStoreProvider.AzureKeyVaultKeyStoreProvider;
50-
import com.microsoft.data.encryption.cryptography.MicrosoftDataEncryptionException;
5150
import io.micrometer.core.instrument.MeterRegistry;
5251
import org.apache.commons.lang3.RandomStringUtils;
5352
import org.mpierce.metrics.reservoir.hdrhistogram.HdrHistogramResetOnSnapshotReservoir;
@@ -59,7 +58,6 @@
5958
import reactor.core.publisher.Mono;
6059
import reactor.util.retry.Retry;
6160

62-
import java.io.FileInputStream;
6361
import java.io.IOException;
6462
import java.io.InputStream;
6563
import java.net.InetSocketAddress;
@@ -85,7 +83,7 @@ public abstract class AsyncEncryptionBenchmark<T> {
8583

8684
private CosmosAsyncContainer cosmosAsyncContainer;
8785
private CosmosAsyncDatabase cosmosAsyncDatabase;
88-
private AzureKeyVaultKeyStoreProvider encryptionKeyStoreProvider = null;
86+
private AzureKeyVaultKeyWrapProvider azureKeyVaultKeyWrapProvider = null;
8987
private Properties keyVaultProperties;
9088

9189
final Logger logger;
@@ -112,7 +110,7 @@ public abstract class AsyncEncryptionBenchmark<T> {
112110

113111
private AtomicBoolean warmupMode = new AtomicBoolean(false);
114112

115-
AsyncEncryptionBenchmark(Configuration cfg) throws IOException, MicrosoftDataEncryptionException {
113+
AsyncEncryptionBenchmark(Configuration cfg) throws IOException {
116114
CosmosClientBuilder cosmosClientBuilder = new CosmosClientBuilder()
117115
.endpoint(cfg.getServiceEndpoint())
118116
.key(cfg.getMasterKey())
@@ -420,14 +418,14 @@ private Properties loadConfig() throws IOException {
420418
}
421419
}
422420

423-
private CosmosEncryptionAsyncClient createEncryptionClientInstance(CosmosAsyncClient cosmosClient) throws MicrosoftDataEncryptionException, IOException {
421+
private CosmosEncryptionAsyncClient createEncryptionClientInstance(CosmosAsyncClient cosmosClient) throws IOException {
424422
keyVaultProperties = loadConfig();
425423
// Application credentials for authentication with Azure Key Vault.
426424
// This application must have keys/wrapKey and keys/unwrapKey permissions
427425
// on the keys that will be used for encryption.
428426
TokenCredential tokenCredentials = getTokenCredential(keyVaultProperties);
429-
encryptionKeyStoreProvider = new AzureKeyVaultKeyStoreProvider(tokenCredentials);
430-
return CosmosEncryptionAsyncClient.createCosmosEncryptionAsyncClient(cosmosClient, encryptionKeyStoreProvider);
427+
azureKeyVaultKeyWrapProvider = new AzureKeyVaultKeyWrapProvider(tokenCredentials);
428+
return CosmosEncryptionAsyncClient.createCosmosEncryptionAsyncClient(cosmosClient, azureKeyVaultKeyWrapProvider);
431429
}
432430

433431
private TokenCredential getTokenCredential(Properties properties) {
@@ -498,7 +496,7 @@ private void createEncryptionDatabaseAndContainer() {
498496
}
499497

500498
EncryptionKeyWrapMetadata metadata =
501-
new EncryptionKeyWrapMetadata(encryptionKeyStoreProvider.getProviderName(), dataEncryptionKeyId,
499+
new EncryptionKeyWrapMetadata(azureKeyVaultKeyWrapProvider.getProviderName(), dataEncryptionKeyId,
502500
masterKeyUrlFromConfig);
503501
/// Generates an encryption key, wraps it using the key wrap metadata provided
504502
/// and saves the wrapped encryption key as an asynchronous operation in the Azure Cosmos service.
@@ -527,23 +525,23 @@ private void createEncryptionDatabaseAndContainer() {
527525
ClientEncryptionIncludedPath includedPath = new ClientEncryptionIncludedPath();
528526
includedPath.setClientEncryptionKeyId(dataEncryptionKeyId);
529527
includedPath.setPath("/" + ENCRYPTED_STRING_FIELD + i);
530-
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC);
528+
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC.toString());
531529
includedPath.setEncryptionAlgorithm(CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256);
532530
encryptionPaths.add(includedPath);
533531
}
534532
for (int i = 1; i <= configuration.getEncryptedDoubleFieldCount(); i++) {
535533
ClientEncryptionIncludedPath includedPath = new ClientEncryptionIncludedPath();
536534
includedPath.setClientEncryptionKeyId(dataEncryptionKeyId);
537535
includedPath.setPath("/" + ENCRYPTED_LONG_FIELD + i);
538-
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC);
536+
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC.toString());
539537
includedPath.setEncryptionAlgorithm(CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256);
540538
encryptionPaths.add(includedPath);
541539
}
542540
for (int i = 1; i <= configuration.getEncryptedLongFieldCount(); i++) {
543541
ClientEncryptionIncludedPath includedPath = new ClientEncryptionIncludedPath();
544542
includedPath.setClientEncryptionKeyId(dataEncryptionKeyId);
545543
includedPath.setPath("/" + ENCRYPTED_DOUBLE_FIELD + i);
546-
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC);
544+
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC.toString());
547545
includedPath.setEncryptionAlgorithm(CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256);
548546
encryptionPaths.add(includedPath);
549547
}

sdk/cosmos/azure-cosmos-benchmark/src/main/java/com/azure/cosmos/benchmark/encryption/AsyncEncryptionWriteBenchmark.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import com.azure.cosmos.models.CosmosItemResponse;
1111
import com.azure.cosmos.models.PartitionKey;
1212
import com.codahale.metrics.Timer;
13-
import com.microsoft.data.encryption.cryptography.MicrosoftDataEncryptionException;
1413
import org.apache.commons.lang3.RandomStringUtils;
1514
import org.reactivestreams.Subscription;
1615
import reactor.core.publisher.BaseSubscriber;
@@ -56,7 +55,7 @@ protected void hookOnError(Throwable throwable) {
5655
}
5756
}
5857

59-
public AsyncEncryptionWriteBenchmark(Configuration cfg) throws IOException, MicrosoftDataEncryptionException {
58+
public AsyncEncryptionWriteBenchmark(Configuration cfg) throws IOException {
6059
super(cfg);
6160
uuid = UUID.randomUUID().toString();
6261
dataFieldValue = RandomStringUtils.randomAlphabetic(configuration.getDocumentDataFieldSize());

sdk/cosmos/azure-cosmos-encryption/README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ CosmosAsyncClient cosmosAsyncClient = new CosmosClientBuilder()
5858
.buildAsyncClient();
5959
CosmosEncryptionAsyncClient cosmosEncryptionAsyncClient =
6060
CosmosEncryptionAsyncClient.createCosmosEncryptionAsyncClient(cosmosAsyncClient,
61-
new AzureKeyVaultKeyStoreProvider(tokenCredentials));
61+
new AzureKeyVaultKeyWrapProvider(tokenCredentials));
6262
```
6363

6464
### Create Cosmos Encryption Database
@@ -81,7 +81,7 @@ You need to first create Container with ClientEncryptionPolicy and using cosmos
8181

8282
```java readme-sample-createCosmosEncryptionContainer
8383
//Create Client Encryption Key
84-
EncryptionKeyWrapMetadata metadata = new EncryptionKeyWrapMetadata(encryptionKeyStoreProvider.getProviderName(), "key", "tempmetadata");
84+
EncryptionKeyWrapMetadata metadata = new EncryptionKeyWrapMetadata(encryptionKeyWrapProvider.getProviderName(), "key", "tempmetadata");
8585
CosmosEncryptionAsyncContainer cosmosEncryptionAsyncContainer = cosmosEncryptionAsyncDatabase
8686
.createClientEncryptionKey("key", CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256, metadata)
8787
// TIP: Our APIs are Reactor Core based, so try to chain your calls
@@ -90,7 +90,7 @@ CosmosEncryptionAsyncContainer cosmosEncryptionAsyncContainer = cosmosEncryption
9090
ClientEncryptionIncludedPath includedPath = new ClientEncryptionIncludedPath();
9191
includedPath.setClientEncryptionKeyId("key");
9292
includedPath.setPath("/sensitiveString");
93-
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC);
93+
includedPath.setEncryptionType(CosmosEncryptionType.DETERMINISTIC.toString());
9494
includedPath.setEncryptionAlgorithm(CosmosEncryptionAlgorithm.AEAD_AES_256_CBC_HMAC_SHA256);
9595

9696
List<ClientEncryptionIncludedPath> paths = new ArrayList<>();
@@ -222,7 +222,7 @@ or contact [opencode@microsoft.com][coc_contact] with any additional questions o
222222
[troubleshooting]: https://docs.microsoft.com/azure/cosmos-db/troubleshoot-java-sdk-v4-sql
223223
[perf_guide]: https://docs.microsoft.com/azure/cosmos-db/performance-tips-java-sdk-v4-sql?tabs=api-async
224224
[sql_api_query]: https://docs.microsoft.com/azure/cosmos-db/sql-api-sql-query
225-
[getting_started_encryption]: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/cosmos/azure-cosmos-encryption/src/samples/java/com/azure/cosmos
225+
[getting_started_encryption]: https://github.com/Azure/azure-sdk-for-java/tree/main/sdk/cosmos/azure-cosmos-encryption/src/samples/java/com/azure/encryption/cosmos
226226
[quickstart]: https://docs.microsoft.com/azure/cosmos-db/create-sql-api-java?tabs=sync
227227

228228
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-java%2Fsdk%2Fcosmos%2Fazure-cosmos-encryption%2FREADME.png)

sdk/cosmos/azure-cosmos-encryption/pom.xml

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,21 @@ Licensed under the MIT License.
3535
<!-- CosmosSkip - Needed temporary values to 10% not fail. -->
3636
<properties>
3737
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
38-
<jacoco.min.linecoverage>0.01</jacoco.min.linecoverage>
39-
<jacoco.min.branchcoverage>0.01</jacoco.min.branchcoverage>
38+
<jacoco.min.linecoverage>0.10</jacoco.min.linecoverage>
39+
<jacoco.min.branchcoverage>0.05</jacoco.min.branchcoverage>
4040

4141
<!-- CosmosSkip - This is not a module we want/expect external customers to consume. Skip breaking API checks. -->
4242
<!-- This can only be enabled once we release GA, as it needs a stable version to check for breaking changes. -->
4343
<revapi.skip>true</revapi.skip>
44+
45+
<!-- Configures the Java 9+ run to perform the required module exports, opens, and reads that are necessary for testing but shouldn't be part of the module-info. -->
46+
<javaModulesSurefireArgLine>
47+
--add-opens com.azure.encryption.cosmos/com.azure.encryption.cosmos=ALL-UNNAMED
48+
--add-opens com.azure.encryption.cosmos/com.azure.encryption.cosmos.implementation=ALL-UNNAMED
49+
--add-opens com.azure.encryption.cosmos/com.azure.encryption.cosmos.keyprovider=ALL-UNNAMED
50+
--add-opens com.azure.encryption.cosmos/com.azure.encryption.cosmos.util=ALL-UNNAMED
51+
--add-opens com.azure.encryption.cosmos/com.azure.encryption.cosmos.models=ALL-UNNAMED
52+
</javaModulesSurefireArgLine>
4453
</properties>
4554

4655
<dependencies>
@@ -199,17 +208,6 @@ Licensed under the MIT License.
199208

200209
<build>
201210
<plugins>
202-
<plugin>
203-
<groupId>org.apache.maven.plugins</groupId>
204-
<artifactId>maven-compiler-plugin</artifactId>
205-
<version>3.8.1</version> <!-- {x-version-update;org.apache.maven.plugins:maven-compiler-plugin;external_dependency} -->
206-
<configuration>
207-
<source>1.8</source>
208-
<target>1.8</target>
209-
<failOnWarning>false</failOnWarning>
210-
</configuration>
211-
</plugin>
212-
213211
<plugin>
214212
<groupId>org.apache.maven.plugins</groupId>
215213
<artifactId>maven-surefire-plugin</artifactId>

sdk/cosmos/azure-cosmos-encryption/src/main/java/com/azure/cosmos/encryption/models/CosmosEncryptionType.java

Lines changed: 0 additions & 19 deletions
This file was deleted.

sdk/cosmos/azure-cosmos-encryption/src/main/java/com/azure/cosmos/encryption/ChangeFeedEncryptionProcessorBuilder.java renamed to sdk/cosmos/azure-cosmos-encryption/src/main/java/com/azure/encryption/cosmos/ChangeFeedEncryptionProcessorBuilder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
package com.azure.cosmos.encryption;
4+
package com.azure.encryption.cosmos;
55

66
import com.azure.cosmos.ChangeFeedProcessor;
77
import com.azure.cosmos.ChangeFeedProcessorBuilder;

sdk/cosmos/azure-cosmos-encryption/src/main/java/com/azure/cosmos/encryption/CosmosEncryptionAsyncClient.java renamed to sdk/cosmos/azure-cosmos-encryption/src/main/java/com/azure/encryption/cosmos/CosmosEncryptionAsyncClient.java

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,21 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4-
package com.azure.cosmos.encryption;
4+
package com.azure.encryption.cosmos;
55

66
import com.azure.cosmos.BridgeInternal;
77
import com.azure.cosmos.CosmosAsyncClient;
88
import com.azure.cosmos.CosmosAsyncClientEncryptionKey;
99
import com.azure.cosmos.CosmosAsyncContainer;
1010
import com.azure.cosmos.CosmosAsyncDatabase;
1111
import com.azure.cosmos.CosmosException;
12+
import com.azure.encryption.cosmos.keyprovider.EncryptionKeyWrapProvider;
1213
import com.azure.cosmos.implementation.HttpConstants;
1314
import com.azure.cosmos.implementation.Utils;
1415
import com.azure.cosmos.implementation.caches.AsyncCache;
15-
import com.azure.cosmos.models.ClientEncryptionPolicy;
1616
import com.azure.cosmos.models.CosmosClientEncryptionKeyProperties;
1717
import com.azure.cosmos.models.CosmosContainerProperties;
1818
import com.azure.cosmos.models.CosmosContainerResponse;
19-
import com.microsoft.data.encryption.cryptography.EncryptionKeyStoreProvider;
2019
import org.slf4j.Logger;
2120
import org.slf4j.LoggerFactory;
2221
import reactor.core.publisher.Mono;
@@ -29,27 +28,27 @@ public class CosmosEncryptionAsyncClient {
2928
private final CosmosAsyncClient cosmosAsyncClient;
3029
private final AsyncCache<String, CosmosContainerProperties> containerPropertiesCacheByContainerId;
3130
private final AsyncCache<String, CosmosClientEncryptionKeyProperties> clientEncryptionKeyPropertiesCacheByKeyId;
32-
private EncryptionKeyStoreProvider encryptionKeyStoreProvider;
31+
private EncryptionKeyWrapProvider encryptionKeyWrapProvider;
3332

3433
CosmosEncryptionAsyncClient(CosmosAsyncClient cosmosAsyncClient,
35-
EncryptionKeyStoreProvider encryptionKeyStoreProvider) {
34+
EncryptionKeyWrapProvider encryptionKeyWrapProvider) {
3635
if (cosmosAsyncClient == null) {
3736
throw new IllegalArgumentException("cosmosClient is null");
3837
}
39-
if (encryptionKeyStoreProvider == null) {
40-
throw new IllegalArgumentException("encryptionKeyStoreProvider is null");
38+
if (encryptionKeyWrapProvider == null) {
39+
throw new IllegalArgumentException("encryptionKeyWrapProvider is null");
4140
}
4241
this.cosmosAsyncClient = cosmosAsyncClient;
43-
this.encryptionKeyStoreProvider = encryptionKeyStoreProvider;
42+
this.encryptionKeyWrapProvider = encryptionKeyWrapProvider;
4443
this.clientEncryptionKeyPropertiesCacheByKeyId = new AsyncCache<>();
4544
this.containerPropertiesCacheByContainerId = new AsyncCache<>();
4645
}
4746

4847
/**
49-
* @return the encryption key store provider
48+
* @return the encryption key wrap provider
5049
*/
51-
public EncryptionKeyStoreProvider getEncryptionKeyStoreProvider() {
52-
return encryptionKeyStoreProvider;
50+
public EncryptionKeyWrapProvider getEncryptionKeyWrapProvider() {
51+
return encryptionKeyWrapProvider;
5352
}
5453

5554
Mono<CosmosContainerProperties> getContainerPropertiesAsync(
@@ -142,13 +141,13 @@ public CosmosAsyncClient getCosmosAsyncClient() {
142141
* Create Cosmos Client with Encryption support for performing operations using client-side encryption.
143142
*
144143
* @param cosmosAsyncClient Regular Cosmos Client.
145-
* @param encryptionKeyStoreProvider encryptionKeyStoreProvider, provider that allows interaction with the master
144+
* @param encryptionKeyWrapProvider encryptionKeyWrapProvider, provider that allows interaction with the master
146145
* keys.
147146
* @return encryptionAsyncCosmosClient to perform operations supporting client-side encryption / decryption.
148147
*/
149148
public static CosmosEncryptionAsyncClient createCosmosEncryptionAsyncClient(CosmosAsyncClient cosmosAsyncClient,
150-
EncryptionKeyStoreProvider encryptionKeyStoreProvider) {
151-
return new CosmosEncryptionAsyncClient(cosmosAsyncClient, encryptionKeyStoreProvider);
149+
EncryptionKeyWrapProvider encryptionKeyWrapProvider) {
150+
return new CosmosEncryptionAsyncClient(cosmosAsyncClient, encryptionKeyWrapProvider);
152151
}
153152

154153
/**

0 commit comments

Comments
 (0)