private async Task <CachedEncryptionSettings> FetchCachedEncryptionSettingsAsync( string propertyName, EncryptionProcessor encryptionProcessor, CancellationToken cancellationToken) { ClientEncryptionPolicy clientEncryptionPolicy = await encryptionProcessor.EncryptionCosmosClient.GetClientEncryptionPolicyAsync( encryptionProcessor.Container, cancellationToken, false); if (clientEncryptionPolicy != null) { foreach (ClientEncryptionIncludedPath propertyToEncrypt in clientEncryptionPolicy.IncludedPaths) { if (string.Equals(propertyToEncrypt.Path.Substring(1), propertyName)) { ClientEncryptionKeyProperties clientEncryptionKeyProperties = await encryptionProcessor.EncryptionCosmosClient.GetClientEncryptionKeyPropertiesAsync( clientEncryptionKeyId : propertyToEncrypt.ClientEncryptionKeyId, container : encryptionProcessor.Container, cancellationToken : cancellationToken, shouldForceRefresh : false); ProtectedDataEncryptionKey protectedDataEncryptionKey = null; try { protectedDataEncryptionKey = this.BuildProtectedDataEncryptionKey( clientEncryptionKeyProperties, encryptionProcessor.EncryptionKeyStoreProvider, propertyToEncrypt.ClientEncryptionKeyId); } catch (RequestFailedException ex) { // the key was revoked. Try to fetch the latest EncryptionKeyProperties from the backend. // This should succeed provided the user has rewraped the key with right set of meta data. if (ex.Status == (int)HttpStatusCode.Forbidden) { clientEncryptionKeyProperties = await encryptionProcessor.EncryptionCosmosClient.GetClientEncryptionKeyPropertiesAsync( clientEncryptionKeyId : propertyToEncrypt.ClientEncryptionKeyId, container : encryptionProcessor.Container, cancellationToken : cancellationToken, shouldForceRefresh : true); protectedDataEncryptionKey = this.BuildProtectedDataEncryptionKey( clientEncryptionKeyProperties, encryptionProcessor.EncryptionKeyStoreProvider, propertyToEncrypt.ClientEncryptionKeyId); } else { throw; } } EncryptionSettings encryptionSettings = new EncryptionSettings { EncryptionSettingTimeToLive = DateTime.UtcNow + TimeSpan.FromMinutes(Constants.CachedEncryptionSettingsDefaultTTLInMinutes), ClientEncryptionKeyId = propertyToEncrypt.ClientEncryptionKeyId, DataEncryptionKey = protectedDataEncryptionKey, }; EncryptionType encryptionType = EncryptionType.Plaintext; switch (propertyToEncrypt.EncryptionType) { case CosmosEncryptionType.Deterministic: encryptionType = EncryptionType.Deterministic; break; case CosmosEncryptionType.Randomized: encryptionType = EncryptionType.Randomized; break; case CosmosEncryptionType.Plaintext: encryptionType = EncryptionType.Plaintext; break; default: throw new ArgumentException($"Invalid encryption type {propertyToEncrypt.EncryptionType}. Please refer to https://aka.ms/CosmosClientEncryption for more details. "); } encryptionSettings = EncryptionSettings.Create(encryptionSettings, encryptionType); return(new CachedEncryptionSettings(encryptionSettings, encryptionSettings.EncryptionSettingTimeToLive)); } } } return(null); }