public async Task BackupAndRestoreAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string secretName = $"StorageAccountPassword{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");

            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            KeyVaultSecret storedSecret = await client.SetSecretAsync(secret);

            string backupPath = Path.GetTempFileName();

            using (FileStream sourceStream = File.Open(backupPath, FileMode.OpenOrCreate))
            {
                byte[] byteSecret = await client.BackupSecretAsync(secretName);

                sourceStream.Seek(0, SeekOrigin.End);
                await sourceStream.WriteAsync(byteSecret, 0, byteSecret.Length);
            }

            // The storage account secret is no longer in use so you delete it.
            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            // Before it can be purged, you need to wait until the secret is fully deleted.
            await operation.WaitForCompletionAsync();

            // If the Key Vault is soft delete-enabled and you want to permanently delete the secret before its `ScheduledPurgeDate`,
            // the deleted secret needs to be purged.
            await client.PurgeDeletedSecretAsync(secretName);

            SecretProperties restoreSecret = null;

            using (FileStream sourceStream = File.Open(backupPath, FileMode.Open))
            {
                byte[] result = new byte[sourceStream.Length];
                await sourceStream.ReadAsync(result, 0, (int)sourceStream.Length);

                restoreSecret = await client.RestoreSecretBackupAsync(result);
            }

            AssertSecretsEqual(storedSecret.Properties, restoreSecret);

            // Delete and purge the restored secret.
            operation = await client.StartDeleteSecretAsync(restoreSecret.Name);

            // You only need to wait for completion if you want to purge or recover the secret.
            await operation.WaitForCompletionAsync();

            await client.PurgeDeletedSecretAsync(restoreSecret.Name);
        }
        public async Task HelloWorldAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");
            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secret);

            KeyVaultSecret bankSecret = await client.GetSecretAsync(secretName);
            Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");

            bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
            SecretProperties updatedSecret = await client.UpdateSecretPropertiesAsync(bankSecret.Properties);
            Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");

            var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa");
            secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secretNewValue);

            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            #region Snippet:SecretsSample1PurgeSecretAsync
            // You only need to wait for completion if you want to purge or recover the secret.
            await operation.WaitForCompletionAsync();

            await client.PurgeDeletedSecretAsync(secretName);
            #endregion
        }
Exemple #3
0
        static async Task <int> Main()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            int       repeat = 0;
            const int total  = 3;

            while (++repeat <= total)
            {
                Console.WriteLine("Repeat #{0}...", repeat);
                try
                {
                    string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

                    var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");
                    secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

                    await client.SetSecretAsync(secret);

                    KeyVaultSecret bankSecret = await client.GetSecretAsync(secretName);

                    Console.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");

                    bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
                    SecretProperties updatedSecret = await client.UpdateSecretPropertiesAsync(bankSecret.Properties);

                    Console.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");

                    var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa");
                    secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

                    await client.SetSecretAsync(secretNewValue);

                    DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

                    #region Snippet:SecretsSample1PurgeSecretAsync
                    // You only need to wait for completion if you want to purge or recover the secret.
                    await operation.WaitForCompletionAsync();

                    await client.PurgeDeletedSecretAsync(secretName);

                    #endregion
                }
                catch (RequestFailedException ex)
                {
                    Console.WriteLine($"Request failed! {ex.Message} {ex.StackTrace}");
                    return(-1);
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Unexpected exception! {ex.Message} {ex.StackTrace}");
                    return(-1);
                }
            }
            Console.WriteLine("Success!");
            return(0);
        }
Exemple #4
0
        public async Task BackupAndRestoreAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");
            string backupPath  = Path.GetTempFileName();

            // Instantiate a secret client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create a secret holding bank account credentials valid for 1 year. if the secret
            // already exists in the key vault, then a new version of the secret is created.
            string secretName = $"StorageAccountPasswor{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v")
            {
                Properties =
                {
                    ExpiresOn = DateTimeOffset.Now.AddYears(1)
                }
            };

            KeyVaultSecret storedSecret = await client.SetSecretAsync(secret);

            // Backups are good to have if in case secrets get accidentally deleted by you.
            // For long term storage, it is ideal to write the backup to a file.
            using (FileStream sourceStream = File.Open(backupPath, FileMode.OpenOrCreate))
            {
                byte[] byteSecret = await client.BackupSecretAsync(secretName);

                sourceStream.Seek(0, SeekOrigin.End);
                await sourceStream.WriteAsync(byteSecret, 0, byteSecret.Length);
            }

            // The storage account secret is no longer in use, so you delete it.
            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            // To ensure the secret is deleted on server before we try to purge it.
            await operation.WaitForCompletionAsync();

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted secret needs to be purged.
            await client.PurgeDeletedSecretAsync(secretName);

            // After sometime, the secret is required again. We can use the backup value to restore it in the key vault.
            SecretProperties restoreSecret = null;

            using (FileStream sourceStream = File.Open(backupPath, FileMode.Open))
            {
                byte[] result = new byte[sourceStream.Length];
                await sourceStream.ReadAsync(result, 0, (int)sourceStream.Length);

                restoreSecret = await client.RestoreSecretBackupAsync(result);
            }

            AssertSecretsEqual(storedSecret.Properties, restoreSecret);
        }
Exemple #5
0
        public async Task DeleteAndPurgeSecretAsync()
        {
            #region Snippet:DeleteAndPurgeSecretAsync
            DeleteSecretOperation operation = await client.StartDeleteSecretAsync("secret-name");

            // You only need to wait for completion if you want to purge or recover the secret.
            await operation.WaitForCompletionAsync();

            DeletedSecret secret = operation.Value;
            await client.PurgeDeletedSecretAsync(secret.Name);

            #endregion
        }
        public async Task OperationCompletion()
        {
            #region Snippet:OperationCompletion
            // create a client
            SecretClient client = new SecretClient(new Uri("http://example.com"), new DefaultAzureCredential());

            // Start the operation
            DeleteSecretOperation operation = await client.StartDeleteSecretAsync("SecretName");

            Response <DeletedSecret> response = await operation.WaitForCompletionAsync();

            DeletedSecret value = response.Value;

            Console.WriteLine(value.Name);
            Console.WriteLine(value.ScheduledPurgeDate);
            #endregion
        }
        protected async Task DeleteSecretsAsync(params string[] names)
        {
            List <Task> tasks = new(names.Length);

            for (int i = 0; i < names.Length; i++)
            {
                string name = names[i];
                Task   t    = Task.Run(async() =>
                {
                    DeleteSecretOperation operation = null;
                    try
                    {
                        operation = await Client.StartDeleteSecretAsync(name);
                        await operation.WaitForCompletionAsync();
                    }
                    catch (RequestFailedException ex) when(ex.Status == 404)
                    {
                    }

                    // Purge deleted Secrets if soft delete is enabled.
                    if (operation.Value.RecoveryId != null)
                    {
                        try
                        {
                            await Client.PurgeDeletedSecretAsync(name);
                        }
                        catch (RequestFailedException ex) when(ex.Status == 404)
                        {
                        }
                    }
                });

                tasks.Add(t);
            }

            await Task.WhenAll(tasks);
        }
        private async Task HelloWorldAsync(string keyVaultUrl)
        {
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string secretName = $"BankAccountPassword-{Guid.NewGuid()}";

            var secret = new KeyVaultSecret(secretName, "f4G34fMh8v");

            secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secret);

            KeyVaultSecret bankSecret = await client.GetSecretAsync(secretName);

            Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}");

            bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1);
            SecretProperties updatedSecret = await client.UpdateSecretPropertiesAsync(bankSecret.Properties);

            Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}");

            var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa");

            secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(secretNewValue);

            DeleteSecretOperation operation = await client.StartDeleteSecretAsync(secretName);

            #region Snippet:SecretsSample1PurgeSecretAsync
            await operation.WaitForCompletionAsync();

            await client.PurgeDeletedSecretAsync(secretName);

            #endregion
        }
Exemple #9
0
        public async Task GetSecretsAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string bankSecretName    = $"BankAccountPassword-{Guid.NewGuid()}";
            string storageSecretName = $"StorageAccountPassword{Guid.NewGuid()}";

            var bankSecret = new KeyVaultSecret(bankSecretName, "f4G34fMh8v");

            bankSecret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            var storageSecret = new KeyVaultSecret(storageSecretName, "f4G34fMh8v547");

            storageSecret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(bankSecret);

            await client.SetSecretAsync(storageSecret);

            Dictionary <string, string> secretValues = new Dictionary <string, string>();

            await foreach (SecretProperties secret in client.GetPropertiesOfSecretsAsync())
            {
                // Getting a disabled secret will fail, so skip disabled secrets.
                if (!secret.Enabled.GetValueOrDefault())
                {
                    continue;
                }

                KeyVaultSecret secretWithValue = await client.GetSecretAsync(secret.Name);

                if (secretValues.ContainsKey(secretWithValue.Value))
                {
                    Debug.WriteLine($"Secret {secretWithValue.Name} shares a value with secret {secretValues[secretWithValue.Value]}");
                }
                else
                {
                    secretValues.Add(secretWithValue.Value, secretWithValue.Name);
                }
            }

            string newBankSecretPassword = "******";

            await foreach (SecretProperties secret in client.GetPropertiesOfSecretVersionsAsync(bankSecretName))
            {
                // Secret versions may also be disabled if compromised and new versions generated, so skip disabled versions, too.
                if (!secret.Enabled.GetValueOrDefault())
                {
                    continue;
                }

                KeyVaultSecret oldBankSecret = await client.GetSecretAsync(secret.Name, secret.Version);

                if (newBankSecretPassword == oldBankSecret.Value)
                {
                    Debug.WriteLine($"Secret {secret.Name} reuses a password");
                }
            }

            await client.SetSecretAsync(bankSecretName, newBankSecretPassword);

            DeleteSecretOperation bankSecretOperation = await client.StartDeleteSecretAsync(bankSecretName);

            DeleteSecretOperation storageSecretOperation = await client.StartDeleteSecretAsync(storageSecretName);

            // You only need to wait for completion if you want to purge or recover the secret.
            await Task.WhenAll(
                bankSecretOperation.WaitForCompletionAsync().AsTask(),
                storageSecretOperation.WaitForCompletionAsync().AsTask());

            await foreach (DeletedSecret secret in client.GetDeletedSecretsAsync())
            {
                Debug.WriteLine($"Deleted secret's recovery Id {secret.RecoveryId}");
            }

            // If the Key Vault is soft delete-enabled, then for permanent deletion, deleted secret needs to be purged.
            await Task.WhenAll(
                client.PurgeDeletedSecretAsync(bankSecretName),
                client.PurgeDeletedSecretAsync(storageSecretName));
        }
        /// <summary>
        /// Demonstrates how to enable soft delete on an existing vault, and then proceeds to delete, recover and purge the vault.
        /// Assumes the caller has the KeyVaultContributor role in the subscription.
        /// </summary>
        /// <returns>Task representing this functionality.</returns>
        public static async Task DemonstrateRecoveryAndPurgeAsync()
        {
            // instantiate the samples object
            var sample = new KeyVaultEntityRecoverySamples();

            var rgName = sample.context.ResourceGroupName;

            // derive a unique vault name for this sample
            var vaultName  = sample.context.VaultName + "invault";
            var secretName = "recoverysample";

            // retrieve the vault (or create, if it doesn't exist)
            var vault = await sample.CreateOrRetrieveVaultAsync(rgName, vaultName, enableSoftDelete : true, enablePurgeProtection : false);

            var vaultUri = vault.Properties.VaultUri;

            SecretClient secretClient = sample.GetDataClient(new Uri(vaultUri));

            Console.WriteLine("Operating with vault name '{0}' in resource group '{1}' and location '{2}'", vaultName, rgName, vault.Location);

            try
            {
                // set a secret
                Console.Write("Setting a new value for secret '{0}'...", secretName);
                await secretClient.SetSecretAsync(secretName, Guid.NewGuid().ToString());

                Console.WriteLine("done.");

                // confirm existence
                Console.Write("Verifying secret creation...");
                Response <KeyVaultSecret> retrievedSecretResponse = await secretClient.GetSecretAsync(secretName);

                Console.WriteLine("done.");

                // confirm recovery is possible
                Console.Write("Verifying the secret deletion is recoverable...");
                var recoveryLevel = retrievedSecretResponse.Value.Properties.RecoveryLevel;
                if (!recoveryLevel.ToLowerInvariant().Contains("Recoverable".ToLowerInvariant()))
                {
                    Console.WriteLine("failed; soft-delete is not enabled for this vault.");

                    return;
                }
                Console.WriteLine("done.");


                // delete secret
                Console.Write("Deleting secret...");
                DeleteSecretOperation deleteSecretOperation = await secretClient.StartDeleteSecretAsync(secretName);

                // When deleting a secret asynchronously before you purge it, you can await the WaitForCompletionAsync method on the operation
                await deleteSecretOperation.WaitForCompletionAsync();

                Console.WriteLine("done.");

                // recover secret
                Console.Write("Recovering deleted secret...");
                RecoverDeletedSecretOperation recoverDeletedSecretOperation = await secretClient.StartRecoverDeletedSecretAsync(secretName);

                await recoverDeletedSecretOperation.WaitForCompletionAsync();

                Console.WriteLine("done.");

                // confirm recovery
                Console.Write("Retrieving recovered secret...");
                await secretClient.GetSecretAsync(secretName);

                Console.WriteLine("done.");

                // delete secret
                Console.Write("Deleting recorvered secret...");
                DeleteSecretOperation deleteRecoveredSecretOperation = await secretClient.StartDeleteSecretAsync(secretName);

                await deleteRecoveredSecretOperation.WaitForCompletionAsync();

                Console.WriteLine("done.");

                // retrieve deleted secret
                Console.Write("Retrieving the deleted secret...");
                await secretClient.GetDeletedSecretAsync(secretName);

                Console.WriteLine("done.");
            }
            catch (RequestFailedException ex)

            {
                Console.WriteLine("Unexpected Key Vault exception encountered: {0}", ex.Message);

                throw;
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception encountered: {0}", e.Message);

                throw;
            }
        }
        /// <summary>
        /// Demonstrates how to back up and restore a secret.
        /// </summary>
        /// <returns>Task representing this functionality.</returns>
        public static async Task DemonstrateBackupAndRestoreAsync()
        {
            // instantiate the samples object
            var sample = new KeyVaultEntityRecoverySamples();

            var rgName = sample.context.ResourceGroupName;

            // derive a unique vault name for this sample
            var vaultName  = sample.context.VaultName + "backuprestore";
            var secretName = "backupsample";

            // retrieve the vault (or create, if it doesn't exist)
            var vault = await sample.CreateOrRetrieveVaultAsync(rgName, vaultName, enableSoftDelete : false, enablePurgeProtection : false);

            var vaultUri = vault.Properties.VaultUri;

            SecretClient secretClient = sample.GetDataClient(new Uri(vaultUri));

            Console.WriteLine("Operating with vault name '{0}' in resource group '{1}' and location '{2}'", vaultName, rgName, vault.Location);

            try
            {
                // set a secret
                Console.Write("Setting a new value for secret '{0}'...", secretName);
                await secretClient.SetSecretAsync(secretName, Guid.NewGuid().ToString());

                Console.WriteLine("done.");

                // confirm existence
                Console.Write("Verifying secret creation...");
                await secretClient.GetSecretAsync(secretName);

                Console.WriteLine("done.");

                // backup secret
                Console.Write("Backing up secret...");
                Response <byte[]> backupResponse = await secretClient.BackupSecretAsync(secretName);

                Console.WriteLine("done.");

                // delete secret
                Console.Write("Deleting secret...");
                DeleteSecretOperation deleteSecretOperation = await secretClient.StartDeleteSecretAsync(secretName);

                // When deleting a secret asynchronously before you purge it, you can await the WaitForCompletionAsync method on the operation
                await deleteSecretOperation.WaitForCompletionAsync();

                Console.WriteLine("done.");

                // restore secret
                Console.Write("Restoring secret from backup...");
                await secretClient.RestoreSecretBackupAsync(backupResponse.Value);

                Console.WriteLine("done.");

                // confirm existence
                Console.Write("Verifying secret restoration...");
                await secretClient.GetSecretAsync(secretName);

                Console.WriteLine("done.");
            }
            catch (RequestFailedException ex)
            {
                Console.WriteLine("Unexpected Key Vault  exception encountered: {0}", ex.Message);

                throw;
            }
            catch (Exception e)
            {
                Console.WriteLine("Unexpected exception encountered: {0}", e.Message);

                throw;
            }
        }
        private async Task MigrationGuide()
        {
            #region Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_Create
            SecretClient client = new SecretClient(
                new Uri("https://myvault.vault.azure.net"),
                new DefaultAzureCredential());
            #endregion Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_Create

            #region Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_CreateWithOptions
            using (HttpClient httpClient = new HttpClient())
            {
                SecretClientOptions options = new SecretClientOptions
                {
                    Transport = new HttpClientTransport(httpClient)
                };

#if SNIPPET
                SecretClient client = new SecretClient(
#else
                SecretClient _ = new SecretClient(
#endif
                    new Uri("https://myvault.vault.azure.net"),
                    new DefaultAzureCredential(),
                    options);
            }
            #endregion Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_CreateWithOptions

            {
                #region Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_SetSecret
                KeyVaultSecret secret = await client.SetSecretAsync("secret-name", "secret-value");

                #endregion Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_SetSecret
            }

            {
                #region Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_GetSecret
                // Get the latest secret value.
                KeyVaultSecret secret = await client.GetSecretAsync("secret-name");

                // Get a specific secret value.
                KeyVaultSecret secretVersion = await client.GetSecretAsync("secret-name", "e43af03a7cbc47d4a4e9f11540186048");

                #endregion Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_GetSecret
            }

            {
                #region Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_ListSecrets
                // List all secrets asynchronously.
                await foreach (SecretProperties item in client.GetPropertiesOfSecretsAsync())
                {
                    KeyVaultSecret secret = await client.GetSecretAsync(item.Name);
                }

                // List all secrets synchronously.
                foreach (SecretProperties item in client.GetPropertiesOfSecrets())
                {
                    KeyVaultSecret secret = client.GetSecret(item.Name);
                }
                #endregion Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_ListSecrets
            }

            {
                #region Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_DeleteSecret
                // Delete the secret.
                DeleteSecretOperation deleteOperation = await client.StartDeleteSecretAsync("secret-name");

                                                                                            // Purge or recover the deleted secret if soft delete is enabled.
                                                                                            if (deleteOperation.Value.RecoveryId != null)
                {
                    // Deleting a secret does not happen immediately. Wait for the secret to be deleted.
                    DeletedSecret deletedSecret = await deleteOperation.WaitForCompletionAsync();

                    // Purge the deleted secret.
                    await client.PurgeDeletedSecretAsync(deletedSecret.Name);

                    // You can also recover the deleted secret using StartRecoverDeletedSecretAsync,
                    // which returns RecoverDeletedSecretOperation you can await like DeleteSecretOperation above.
                }
                                                                                            #endregion Snippet:Azure_Security_KeyVault_Secrets_Snippets_MigrationGuide_DeleteSecret
            }
        }
        private async Task GetSecretsAsync(string keyVaultUrl)
        {
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            string bankSecretName    = $"BankAccountPassword-{Guid.NewGuid()}";
            string storageSecretName = $"StorageAccountPassword{Guid.NewGuid()}";

            var bankSecret = new KeyVaultSecret(bankSecretName, "f4G34fMh8v");

            bankSecret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            var storageSecret = new KeyVaultSecret(storageSecretName, "f4G34fMh8v547");

            storageSecret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1);

            await client.SetSecretAsync(bankSecret);

            await client.SetSecretAsync(storageSecret);

            Dictionary <string, string> secretValues = new Dictionary <string, string>();

            await foreach (SecretProperties secret in client.GetPropertiesOfSecretsAsync())
            {
                KeyVaultSecret secretWithValue = await client.GetSecretAsync(secret.Name);

                if (secretValues.ContainsKey(secretWithValue.Value))
                {
                    throw new InvalidOperationException($"Secret {secretWithValue.Name} shares a value with secret {secretValues[secretWithValue.Value]}");
                }

                secretValues.Add(secretWithValue.Value, secretWithValue.Name);
            }

            string newBankSecretPassword = "******";

            await foreach (SecretProperties secret in client.GetPropertiesOfSecretVersionsAsync(bankSecretName))
            {
                KeyVaultSecret oldBankSecret = await client.GetSecretAsync(secret.Name, secret.Version);

                if (newBankSecretPassword == oldBankSecret.Value)
                {
                    throw new InvalidOperationException($"Secret {secret.Name} reuses a password");
                }
            }

            await client.SetSecretAsync(bankSecretName, newBankSecretPassword);

            DeleteSecretOperation bankSecretOperation = await client.StartDeleteSecretAsync(bankSecretName);

            DeleteSecretOperation storageSecretOperation = await client.StartDeleteSecretAsync(storageSecretName);

            Task.WaitAll(
                bankSecretOperation.WaitForCompletionAsync().AsTask(),
                storageSecretOperation.WaitForCompletionAsync().AsTask());

            await foreach (DeletedSecret secret in client.GetDeletedSecretsAsync())
            {
                Debug.WriteLine($"Deleted secret's recovery Id {secret.RecoveryId}");
            }

            // If the Key Vault is soft delete-enabled, then for permanent deletion, deleted secret needs to be purged.
            Task.WaitAll(
                client.PurgeDeletedSecretAsync(bankSecretName),
                client.PurgeDeletedSecretAsync(storageSecretName));
        }
        public async Task GetSecretsAsync()
        {
            // Environment variable with the Key Vault endpoint.
            string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL");

            // Instantiate a secret client that will be used to call the service. Notice that the client is using default Azure
            // credentials. To make default credentials work, ensure that environment variables 'AZURE_CLIENT_ID',
            // 'AZURE_CLIENT_KEY' and 'AZURE_TENANT_ID' are set with the service principal credentials.
            var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());

            // Let's create secrets holding storage and bank accounts credentials valid for 1 year. if the secret
            // already exists in the key vault, then a new version of the secret is created.
            string bankSecretName    = $"BankAccountPassword-{Guid.NewGuid()}";
            string storageSecretName = $"StorageAccountPasswor{Guid.NewGuid()}";

            var bankSecret = new KeyVaultSecret(bankSecretName, "f4G34fMh8v")
            {
                Properties =
                {
                    ExpiresOn = DateTimeOffset.Now.AddYears(1)
                }
            };

            var storageSecret = new KeyVaultSecret(storageSecretName, "f4G34fMh8v547")
            {
                Properties =
                {
                    ExpiresOn = DateTimeOffset.Now.AddYears(1)
                }
            };

            await client.SetSecretAsync(bankSecret);

            await client.SetSecretAsync(storageSecret);

            // You need to check if any of the secrets are sharing same values. Let's list the secrets and print their values.
            // List operations don't return the secrets with value information.
            // So, for each returned secret we call Get to get the secret with its value information.
            await foreach (SecretProperties secret in client.GetPropertiesOfSecretsAsync())
            {
                KeyVaultSecret secretWithValue = await client.GetSecretAsync(secret.Name);

                Debug.WriteLine($"Secret is returned with name {secretWithValue.Name} and value {secretWithValue.Value}");
            }

            // The bank account password got updated, so you want to update the secret in key vault to ensure it reflects the new password.
            // Calling Set on an existing secret creates a new version of the secret in the key vault with the new value.
            await client.SetSecretAsync(bankSecretName, "sskdjfsdasdjsd");

            // You need to check all the different values your bank account password secret had previously.
            // Lets print all the versions of this secret.
            await foreach (SecretProperties secret in client.GetPropertiesOfSecretVersionsAsync(bankSecretName))
            {
                Debug.WriteLine($"Secret's version {secret.Version} with name {secret.Name}");
            }

            // The bank account was closed. You need to delete its credentials from the key vault.
            // You also want to delete the information of your storage account.
            DeleteSecretOperation bankSecretOperation = await client.StartDeleteSecretAsync(bankSecretName);

            DeleteSecretOperation storageSecretOperation = await client.StartDeleteSecretAsync(storageSecretName);

            // To ensure the secrets are deleted on server before we try to purge them.
            Task.WaitAll(
                bankSecretOperation.WaitForCompletionAsync().AsTask(),
                storageSecretOperation.WaitForCompletionAsync().AsTask());

            // You can list all the deleted and non-purged secrets, assuming key vault is soft-delete enabled.
            await foreach (DeletedSecret secret in client.GetDeletedSecretsAsync())
            {
                Debug.WriteLine($"Deleted secret's recovery Id {secret.RecoveryId}");
            }

            // If the keyvault is soft-delete enabled, then for permanent deletion, deleted secret needs to be purged.
            Task.WaitAll(
                client.PurgeDeletedSecretAsync(bankSecretName),
                client.PurgeDeletedSecretAsync(storageSecretName));
        }