private bool VerifyClientEncryptionIncludedPath(ClientEncryptionIncludedPath expected, ClientEncryptionIncludedPath actual)
 {
     return(expected.Path == actual.Path &&
            expected.ClientEncryptionKeyId == actual.ClientEncryptionKeyId &&
            expected.EncryptionType == actual.EncryptionType &&
            expected.EncryptionAlgorithm == actual.EncryptionAlgorithm);
 }
예제 #2
0
 private static EncryptionType GetEncryptionTypeForProperty(ClientEncryptionIncludedPath clientEncryptionIncludedPath)
 {
     return(clientEncryptionIncludedPath.EncryptionType switch
     {
         CosmosEncryptionType.Deterministic => EncryptionType.Deterministic,
         CosmosEncryptionType.Randomized => EncryptionType.Randomized,
         _ => throw new ArgumentException($"Invalid encryption type {clientEncryptionIncludedPath.EncryptionType}. Please refer to https://aka.ms/CosmosClientEncryption for more details. "),
     });
        public PSClientEncryptionIncludedPath(ClientEncryptionIncludedPath clientEncryptionIncludedPath)
        {
            if (clientEncryptionIncludedPath == null)
            {
                return;
            }

            Path = clientEncryptionIncludedPath.Path;
            ClientEncryptionKeyId = clientEncryptionIncludedPath.ClientEncryptionKeyId;
            EncryptionType        = clientEncryptionIncludedPath.EncryptionType;
            EncryptionAlgorithm   = clientEncryptionIncludedPath.EncryptionAlgorithm;
        }
예제 #4
0
        internal EncryptionType GetEncryptionTypeForProperty(ClientEncryptionIncludedPath clientEncryptionIncludedPath)
        {
            switch (clientEncryptionIncludedPath.EncryptionType)
            {
            case CosmosEncryptionType.Deterministic:
                return(EncryptionType.Deterministic);

            case CosmosEncryptionType.Randomized:
                return(EncryptionType.Randomized);

            case CosmosEncryptionType.Plaintext:
                return(EncryptionType.Plaintext);

            default:
                throw new ArgumentException($"Invalid encryption type {clientEncryptionIncludedPath.EncryptionType}. Please refer to https://aka.ms/CosmosClientEncryption for more details. ");
            }
        }
예제 #5
0
        private static void ValidateClientEncryptionIncludedPath(ClientEncryptionIncludedPath clientEncryptionIncludedPath)
        {
            if (clientEncryptionIncludedPath == null)
            {
                throw new ArgumentNullException(nameof(clientEncryptionIncludedPath));
            }

            if (string.IsNullOrWhiteSpace(clientEncryptionIncludedPath.Path))
            {
                throw new ArgumentNullException(nameof(clientEncryptionIncludedPath.Path));
            }

            if (clientEncryptionIncludedPath.Path[0] != '/' ||
                clientEncryptionIncludedPath.Path.LastIndexOf('/') != 0 ||
                string.Equals(clientEncryptionIncludedPath.Path.Substring(1), "id"))
            {
                throw new ArgumentException($"Invalid path '{clientEncryptionIncludedPath.Path ?? string.Empty}'.");
            }

            if (string.IsNullOrWhiteSpace(clientEncryptionIncludedPath.ClientEncryptionKeyId))
            {
                throw new ArgumentNullException(nameof(clientEncryptionIncludedPath.ClientEncryptionKeyId));
            }

            if (string.IsNullOrWhiteSpace(clientEncryptionIncludedPath.EncryptionType))
            {
                throw new ArgumentNullException(nameof(clientEncryptionIncludedPath.EncryptionType));
            }

            if (!string.Equals(clientEncryptionIncludedPath.EncryptionType, "Deterministic") &&
                !string.Equals(clientEncryptionIncludedPath.EncryptionType, "Randomized"))
            {
                throw new ArgumentException("EncryptionType should be either 'Deterministic' or 'Randomized'. ", nameof(clientEncryptionIncludedPath));
            }

            if (string.IsNullOrWhiteSpace(clientEncryptionIncludedPath.EncryptionAlgorithm))
            {
                throw new ArgumentNullException(nameof(clientEncryptionIncludedPath.EncryptionAlgorithm));
            }

            if (!string.Equals(clientEncryptionIncludedPath.EncryptionAlgorithm, "AEAD_AES_256_CBC_HMAC_SHA256"))
            {
                throw new ArgumentException("EncryptionAlgorithm should be 'AEAD_AES_256_CBC_HMAC_SHA256'. ", nameof(clientEncryptionIncludedPath));
            }
        }
        public async Task WithClientEncryptionPolicyTest()
        {
            string containerName               = Guid.NewGuid().ToString();
            string partitionKeyPath            = "/users";
            ClientEncryptionIncludedPath path1 = new ClientEncryptionIncludedPath()
            {
                Path = "/path1",
                ClientEncryptionKeyId = "key1",
                EncryptionType        = "Randomized",
                EncryptionAlgorithm   = "AEAD_AES_256_CBC_HMAC_SHA256"
            };

            ClientEncryptionIncludedPath path2 = new ClientEncryptionIncludedPath()
            {
                Path = "/path2",
                ClientEncryptionKeyId = "key2",
                EncryptionType        = "Randomized",
                EncryptionAlgorithm   = "AEAD_AES_256_CBC_HMAC_SHA256",
            };

            ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                  .WithClientEncryptionPolicy()
                                                  .WithIncludedPath(path1)
                                                  .WithIncludedPath(path2)
                                                  .Attach()
                                                  .CreateAsync();

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Container           container        = containerResponse;
            ContainerProperties responseSettings = containerResponse;

            Assert.IsNotNull(responseSettings.ClientEncryptionPolicy);
            Assert.AreEqual(2, responseSettings.ClientEncryptionPolicy.IncludedPaths.Count());
            ClientEncryptionIncludedPath clientEncryptionIncludedPath = responseSettings.ClientEncryptionPolicy.IncludedPaths.First();

            Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(path1, clientEncryptionIncludedPath));
            clientEncryptionIncludedPath = responseSettings.ClientEncryptionPolicy.IncludedPaths.Last();
            Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(path2, clientEncryptionIncludedPath));

            ContainerResponse readResponse = await container.ReadContainerAsync();

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Assert.IsNotNull(readResponse.Resource.ClientEncryptionPolicy);
        }
예제 #7
0
        public static ClientEncryptionPolicy ToSDKModel(PSClientEncryptionPolicy pSClientEncryptionPolicy, List <string> partitionKeyPathTokens)
        {
            if (pSClientEncryptionPolicy == null)
            {
                return(null);
            }

            ClientEncryptionPolicy clientEncryptionPolicy = new ClientEncryptionPolicy
            {
                IncludedPaths       = new List <ClientEncryptionIncludedPath>(),
                PolicyFormatVersion = pSClientEncryptionPolicy.PolicyFormatVersion
            };

            if (ModelHelper.IsNotNullOrEmpty(pSClientEncryptionPolicy.IncludedPaths))
            {
                foreach (PSClientEncryptionIncludedPath includedPath in pSClientEncryptionPolicy.IncludedPaths)
                {
                    ClientEncryptionIncludedPath clientEncryptionIncludedPath = new ClientEncryptionIncludedPath
                    {
                        Path = includedPath.Path,
                        ClientEncryptionKeyId = includedPath.ClientEncryptionKeyId,
                        EncryptionAlgorithm   = includedPath.EncryptionAlgorithm,
                        EncryptionType        = includedPath.EncryptionType
                    };

                    clientEncryptionPolicy.IncludedPaths.Add(clientEncryptionIncludedPath);
                }
            }

            PSClientEncryptionPolicy.ValidatePartitionKeyPathsAreNotEncrypted(clientEncryptionPolicy.IncludedPaths, partitionKeyPathTokens);

            if (clientEncryptionPolicy.PolicyFormatVersion != 1)
            {
                throw new InvalidOperationException($"Invalid PolicyFormatVersion:{clientEncryptionPolicy.PolicyFormatVersion} used in Client Encryption Policy. ");
            }

            return(clientEncryptionPolicy);
        }
        public async Task WithClientEncryptionPolicyFailureTest()
        {
            string containerName               = Guid.NewGuid().ToString();
            string partitionKeyPath            = "/users";
            ClientEncryptionIncludedPath path1 = new ClientEncryptionIncludedPath()
            {
                ClientEncryptionKeyId = "key1",
                EncryptionType        = "random",
                EncryptionAlgorithm   = "LegacyAeadAes256CbcHmac256"
            };

            // Null value for Path
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateColleciton with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentNullException ex)
            {
                Assert.IsTrue(ex.Message.Contains("Parameter name: Path"));
            }

            path1.Path = "/path";

            // Invalid EncryptionType
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateColleciton with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("EncryptionType should be either 'Deterministic' or 'Randomized' or 'Plaintext'."));
            }

            path1.EncryptionType = "Deterministic";

            // Invalid EncryptionAlgorithm
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateColleciton with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("EncryptionAlgorithm should be 'AEAD_AES_256_CBC_HMAC_SHA256'."));
            }
        }
        public async Task ContainerContractTest()
        {
            ClientEncryptionIncludedPath clientEncryptionIncludedPath1 = new ClientEncryptionIncludedPath()
            {
                Path = "/path",
                ClientEncryptionKeyId = "dekId",
                EncryptionAlgorithm   = "AEAD_AES_256_CBC_HMAC_SHA256",
                EncryptionType        = "Randomized"
            };

            Collection <ClientEncryptionIncludedPath> paths = new Collection <ClientEncryptionIncludedPath>()
            {
                clientEncryptionIncludedPath1
            };

            ContainerProperties containerProperties = new ContainerProperties(Guid.NewGuid().ToString(), "/users")
            {
                IndexingPolicy = new IndexingPolicy()
                {
                    Automatic     = true,
                    IndexingMode  = IndexingMode.Consistent,
                    IncludedPaths = new Collection <IncludedPath>()
                    {
                        new IncludedPath()
                        {
                            Path = "/*"
                        }
                    },
                    ExcludedPaths = new Collection <ExcludedPath>()
                    {
                        new ExcludedPath()
                        {
                            Path = "/test/*"
                        }
                    },
                    CompositeIndexes = new Collection <Collection <CompositePath> >()
                    {
                        new Collection <CompositePath>()
                        {
                            new CompositePath()
                            {
                                Path  = "/address/city",
                                Order = CompositePathSortOrder.Ascending
                            },
                            new CompositePath()
                            {
                                Path  = "/address/zipcode",
                                Order = CompositePathSortOrder.Descending
                            }
                        }
                    },
                    SpatialIndexes = new Collection <SpatialPath>()
                    {
                        new SpatialPath()
                        {
                            Path         = "/address/spatial/*",
                            SpatialTypes = new Collection <SpatialType>()
                            {
                                SpatialType.LineString
                            }
                        }
                    }
                },
                ClientEncryptionPolicy = new ClientEncryptionPolicy(paths)
            };

            CosmosJsonDotNetSerializer serializer = new CosmosJsonDotNetSerializer();
            Stream stream = serializer.ToStream(containerProperties);
            ContainerProperties deserialziedTest = serializer.FromStream <ContainerProperties>(stream);

            ContainerResponse response = await this.database.CreateContainerAsync(containerProperties);

            Assert.IsNotNull(response);
            Assert.IsTrue(response.RequestCharge > 0);
            Assert.IsNotNull(response.Headers);
            Assert.IsNotNull(response.Headers.ActivityId);

            ContainerProperties responseProperties = response.Resource;

            Assert.IsNotNull(responseProperties.Id);
            Assert.IsNotNull(responseProperties.ResourceId);
            Assert.IsNotNull(responseProperties.ETag);
            Assert.IsTrue(responseProperties.LastModified.HasValue);

            Assert.IsTrue(responseProperties.LastModified.Value > new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc), responseProperties.LastModified.Value.ToString());

            Assert.AreEqual(1, responseProperties.IndexingPolicy.IncludedPaths.Count);
            IncludedPath includedPath = responseProperties.IndexingPolicy.IncludedPaths.First();

            Assert.AreEqual("/*", includedPath.Path);

            Assert.AreEqual("/test/*", responseProperties.IndexingPolicy.ExcludedPaths.First().Path);

            Assert.AreEqual(1, responseProperties.IndexingPolicy.CompositeIndexes.Count);
            Assert.AreEqual(2, responseProperties.IndexingPolicy.CompositeIndexes.First().Count);
            CompositePath compositePath = responseProperties.IndexingPolicy.CompositeIndexes.First().First();

            Assert.AreEqual("/address/city", compositePath.Path);
            Assert.AreEqual(CompositePathSortOrder.Ascending, compositePath.Order);

            Assert.AreEqual(1, responseProperties.IndexingPolicy.SpatialIndexes.Count);
            SpatialPath spatialPath = responseProperties.IndexingPolicy.SpatialIndexes.First();

            Assert.AreEqual("/address/spatial/*", spatialPath.Path);
            Assert.AreEqual(4, spatialPath.SpatialTypes.Count); // All SpatialTypes are returned

            Assert.AreEqual(1, responseProperties.ClientEncryptionPolicy.IncludedPaths.Count());
            Assert.AreEqual(1, responseProperties.ClientEncryptionPolicy.PolicyFormatVersion);
            ClientEncryptionIncludedPath clientEncryptionIncludedPath = responseProperties.ClientEncryptionPolicy.IncludedPaths.First();

            Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(clientEncryptionIncludedPath1, clientEncryptionIncludedPath));
        }
예제 #10
0
        public async Task WithClientEncryptionPolicyTest()
        {
            // create ClientEncryptionKeys
            DatabaseInlineCore databaseInlineCore = (DatabaseInlineCore)this.database;
            await TestCommon.CreateClientEncryptionKey("dekId1", databaseInlineCore);

            await TestCommon.CreateClientEncryptionKey("dekId2", databaseInlineCore);

            string containerName               = Guid.NewGuid().ToString();
            string partitionKeyPath            = "/users";
            ClientEncryptionIncludedPath path1 = new ClientEncryptionIncludedPath()
            {
                Path = "/path1",
                ClientEncryptionKeyId = "dekId1",
                EncryptionType        = "Randomized",
                EncryptionAlgorithm   = "AEAD_AES_256_CBC_HMAC_SHA256"
            };

            ClientEncryptionIncludedPath path2 = new ClientEncryptionIncludedPath()
            {
                Path = "/path2",
                ClientEncryptionKeyId = "dekId2",
                EncryptionType        = "Randomized",
                EncryptionAlgorithm   = "AEAD_AES_256_CBC_HMAC_SHA256",
            };

            ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                  .WithClientEncryptionPolicy()
                                                  .WithIncludedPath(path1)
                                                  .WithIncludedPath(path2)
                                                  .Attach()
                                                  .CreateAsync();

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Container           container        = containerResponse;
            ContainerProperties responseSettings = containerResponse;

            Assert.IsNotNull(responseSettings.ClientEncryptionPolicy);
            Assert.AreEqual(2, responseSettings.ClientEncryptionPolicy.IncludedPaths.Count());
            ClientEncryptionIncludedPath clientEncryptionIncludedPath = responseSettings.ClientEncryptionPolicy.IncludedPaths.First();

            Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(path1, clientEncryptionIncludedPath));
            clientEncryptionIncludedPath = responseSettings.ClientEncryptionPolicy.IncludedPaths.Last();
            Assert.IsTrue(this.VerifyClientEncryptionIncludedPath(path2, clientEncryptionIncludedPath));

            ContainerResponse readResponse = await container.ReadContainerAsync();

            Assert.AreEqual(HttpStatusCode.Created, containerResponse.StatusCode);
            Assert.IsNotNull(readResponse.Resource.ClientEncryptionPolicy);

            // update CEP and replace container
            readResponse.Resource.ClientEncryptionPolicy = null;
            try
            {
                await container.ReplaceContainerAsync(readResponse.Resource);

                Assert.Fail("ReplaceCollection with update to ClientEncryptionPolicy should have failed.");
            }
            catch (CosmosException ex)
            {
                Assert.AreEqual(HttpStatusCode.BadRequest, ex.StatusCode);
                Assert.IsTrue(ex.Message.Contains("'clientEncryptionPolicy' cannot be changed as part of collection replace operation."));
            }
        }
예제 #11
0
        public async Task WithClientEncryptionPolicyFailureTest()
        {
            string containerName               = Guid.NewGuid().ToString();
            string partitionKeyPath            = "/users";
            ClientEncryptionIncludedPath path1 = new ClientEncryptionIncludedPath()
            {
                ClientEncryptionKeyId = "key1",
                EncryptionType        = "random",
                EncryptionAlgorithm   = "LegacyAeadAes256CbcHmac256"
            };

            // Null value for Path
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentNullException ex)
            {
                Assert.IsTrue(ex.Message.Contains("Parameter 'Path'"));
            }

            path1.Path = "/path";

            // Invalid EncryptionType
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("EncryptionType should be either 'Deterministic' or 'Randomized'. "));
            }

            path1.EncryptionType = "Plaintext";

            // Invalid EncryptionType
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("EncryptionType should be either 'Deterministic' or 'Randomized'. "));
            }

            path1.EncryptionType = "Deterministic";

            // Invalid EncryptionAlgorithm
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("EncryptionAlgorithm should be 'AEAD_AES_256_CBC_HMAC_SHA256'. "));
            }

            // invalid policy version for partition key encryption
            path1.EncryptionAlgorithm = "AEAD_AES_256_CBC_HMAC_SHA256";
            path1.Path = partitionKeyPath;
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("Path: /users which is part of the partition key cannot be encrypted with PolicyFormatVersion: 1. Please use PolicyFormatVersion: 2."), ex.Message);
            }

            // invalid policy version for id encryption
            path1.Path = "/id";
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy()
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("Path: /id cannot be encrypted with PolicyFormatVersion: 1. Please use PolicyFormatVersion: 2."), ex.Message);
            }

            // invalid encryption type for id encryption
            path1.EncryptionType = "Randomized";
            path1.Path           = partitionKeyPath;
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy(policyFormatVersion: 2)
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("Path: /users which is part of the partition key has to be encrypted with Deterministic type Encryption."), ex.Message);
            }

            // invalid encryption type for id encryption
            path1.Path = "/id";
            try
            {
                ContainerResponse containerResponse = await this.database.DefineContainer(containerName, partitionKeyPath)
                                                      .WithClientEncryptionPolicy(policyFormatVersion: 2)
                                                      .WithIncludedPath(path1)
                                                      .Attach()
                                                      .CreateAsync();

                Assert.Fail("CreateCollection with invalid ClientEncryptionPolicy should have failed.");
            }
            catch (ArgumentException ex)
            {
                Assert.IsTrue(ex.Message.Contains("Only Deterministic encryption type is supported for path: /id."), ex.Message);
            }
        }
예제 #12
0
 /// <summary>
 /// Adds a <see cref="ClientEncryptionIncludedPath"/> to the current <see cref="ClientEncryptionPolicyDefinition"/>.
 /// </summary>
 /// <param name="path">ClientEncryptionIncludedPath to add.</param>
 /// <returns>An instance of the current <see cref="ClientEncryptionPolicyDefinition"/>.</returns>
 public ClientEncryptionPolicyDefinition WithIncludedPath(ClientEncryptionIncludedPath path)
 {
     this.clientEncryptionIncludedPaths.Add(path);
     return(this);
 }
예제 #13
0
 public PSSqlClientEncryptionIncludedPath(ClientEncryptionIncludedPath clientEncryptionIncludedPath) : base(clientEncryptionIncludedPath)
 {
 }
예제 #14
0
        /// <summary>
        /// Administrative operations - create the database, container, and generate the necessary client encryption keys.
        /// These are initializations and are expected to be invoked only once - do not invoke these before every item request.
        /// </summary>
        private static async Task AdminSetupAsync(CosmosClient client)
        {
            Database database = await client.CreateDatabaseIfNotExistsAsync(Program.encryptedDatabaseId);

            // Delete the existing container to prevent create item conflicts.
            using (await database.GetContainer(Program.encryptedContainerId).DeleteContainerStreamAsync())
            { }

            Console.WriteLine("The demo will create a 1000 RU/s container, press any key to continue.");
            Console.ReadKey();

            // Create the Client Encryption Keys for Encrypting the configured Paths.
            await database.CreateClientEncryptionKeyAsync(
                "key1",
                DataEncryptionAlgorithm.AeadAes256CbcHmacSha256,
                new EncryptionKeyWrapMetadata(
                    KeyEncryptionKeyResolverName.AzureKeyVault,
                    "akvMasterKey",
                    MasterKeyUrl,
                    EncryptionAlgorithm.RsaOaep.ToString()));

            await database.CreateClientEncryptionKeyAsync(
                "key2",
                DataEncryptionAlgorithm.AeadAes256CbcHmacSha256,
                new EncryptionKeyWrapMetadata(
                    KeyEncryptionKeyResolverName.AzureKeyVault,
                    "akvMasterKey",
                    MasterKeyUrl,
                    EncryptionAlgorithm.RsaOaep.ToString()));

            // Configure the required Paths to be Encrypted with appropriate settings.
            ClientEncryptionIncludedPath path1 = new ClientEncryptionIncludedPath()
            {
                Path = "/SubTotal",
                ClientEncryptionKeyId = "key1",
                EncryptionType        = EncryptionType.Deterministic,
                EncryptionAlgorithm   = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
            };

            // non primitive data type.Leaves get encrypted.
            ClientEncryptionIncludedPath path2 = new ClientEncryptionIncludedPath()
            {
                Path = "/Items",
                ClientEncryptionKeyId = "key2",
                EncryptionType        = EncryptionType.Deterministic,
                EncryptionAlgorithm   = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
            };

            ClientEncryptionIncludedPath path3 = new ClientEncryptionIncludedPath()
            {
                Path = "/OrderDate",
                ClientEncryptionKeyId = "key1",
                EncryptionType        = EncryptionType.Deterministic,
                EncryptionAlgorithm   = DataEncryptionAlgorithm.AeadAes256CbcHmacSha256
            };

            // Create a container with the appropriate partition key definition (we choose the "AccountNumber" property here) and throughput (we choose 1000 here).
            // Configure the Client Encryption Key Policy with required paths to be encrypted.
            await database.DefineContainer(Program.encryptedContainerId, "/AccountNumber")
            .WithClientEncryptionPolicy()
            .WithIncludedPath(path1)
            .WithIncludedPath(path2)
            .WithIncludedPath(path3)
            .Attach()
            .CreateAsync(throughput: 1000);

            // gets a Container with Encryption Support.
            containerWithEncryption = await database.GetContainer(Program.encryptedContainerId).InitializeEncryptionAsync();
        }