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); }
public async Task StartRecoverDeletedSecret() { string secretName = Recording.GenerateId(); KeyVaultSecret secret = await Client.SetSecretAsync(secretName, "value"); RegisterForCleanup(secret.Name); DeleteSecretOperation deleteOperation = await Client.StartDeleteSecretAsync(secretName); DeletedSecret deletedSecret = deleteOperation.Value; await WaitForDeletedSecret(secretName); RecoverDeletedSecretOperation operation = await Client.StartRecoverDeletedSecretAsync(secretName); SecretProperties recoverSecretResult = operation.Value; await WaitForSecret(secretName); KeyVaultSecret recoveredSecret = await Client.GetSecretAsync(secretName); AssertSecretPropertiesEqual(secret.Properties, deletedSecret.Properties); AssertSecretPropertiesEqual(secret.Properties, recoverSecretResult); AssertSecretsEqual(secret, recoveredSecret); }
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 }
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); }
public async Task DeleteSecret() { #region DeleteSecret DeleteSecretOperation operation = await client.StartDeleteSecretAsync("secret-name"); DeletedSecret secret = operation.Value; Console.WriteLine(secret.Name); Console.WriteLine(secret.Value); #endregion }
public void DeleteSecret() { #region Snippet:DeleteSecret DeleteSecretOperation operation = client.StartDeleteSecret("secret-name"); DeletedSecret secret = operation.Value; Console.WriteLine(secret.Name); Console.WriteLine(secret.Value); #endregion }
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 void HelloWorldSync() { // Environment variable with the Key Vault endpoint. string keyVaultUrl = Environment.GetEnvironmentVariable("AZURE_KEYVAULT_URL"); #region Snippet:SecretsSample1SecretClient var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); #endregion #region Snippet:SecretsSample1CreateSecret string secretName = $"BankAccountPassword-{Guid.NewGuid()}"; var secret = new KeyVaultSecret(secretName, "f4G34fMh8v"); secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1); client.SetSecret(secret); #endregion #region Snippet:SecretsSample1GetSecret KeyVaultSecret bankSecret = client.GetSecret(secretName); Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}"); #endregion #region Snippet:SecretsSample1UpdateSecretProperties bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1); SecretProperties updatedSecret = client.UpdateSecretProperties(bankSecret.Properties); Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}"); #endregion #region Snippet:SecretsSample1UpdateSecret var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa"); secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1); client.SetSecret(secretNewValue); #endregion #region Snippet:SecretsSample1DeleteSecret DeleteSecretOperation operation = client.StartDeleteSecret(secretName); #endregion #region Snippet:SecretsSample1PurgeSecret // You only need to wait for completion if you want to purge or recover the secret. while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } client.PurgeDeletedSecret(secretName); #endregion }
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 }
private void HelloWorldSync(string keyVaultUrl) { #region Snippet:SecretsSample1SecretClient var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); #endregion #region Snippet:SecretsSample1CreateSecret string secretName = $"BankAccountPassword-{Guid.NewGuid()}"; var secret = new KeyVaultSecret(secretName, "f4G34fMh8v"); secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1); client.SetSecret(secret); #endregion #region Snippet:SecretsSample1GetSecret KeyVaultSecret bankSecret = client.GetSecret(secretName); Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}"); #endregion #region Snippet:SecretsSample1UpdateSecretProperties bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1); SecretProperties updatedSecret = client.UpdateSecretProperties(bankSecret.Properties); Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}"); #endregion #region Snippet:SecretsSample1UpdateSecret var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa"); secretNewValue.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1); client.SetSecret(secretNewValue); #endregion #region Snippet:SecretsSample1DeleteSecret DeleteSecretOperation operation = client.StartDeleteSecret(secretName); #endregion #region Snippet:SecretsSample1PurgeSecret while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } client.PurgeDeletedSecret(secretName); #endregion }
public void BackupAndRestoreSync() { // 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 = client.SetSecret(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. File.WriteAllBytes(backupPath, client.BackupSecret(secretName)); // The storage account secret is no longer in use, so you delete it. DeleteSecretOperation operation = client.StartDeleteSecret(secretName); // To ensure the secret is deleted on server before we try to purge it. while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } // If the keyvault is soft-delete enabled, then for permanent deletion, deleted secret needs to be purged. client.PurgeDeletedSecret(secretName); // After sometime, the secret is required again. We can use the backup value to restore it in the key vault. SecretProperties restoreSecret = client.RestoreSecretBackup(File.ReadAllBytes(backupPath)); AssertSecretsEqual(storedSecret.Properties, restoreSecret); }
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 }
public void DeleteSecretSync() { #region DeleteSecretSync DeleteSecretOperation operation = client.StartDeleteSecret("secret-name"); // You only need to wait for completion if you want to purge or recover the secret. while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } DeletedSecret secret = operation.Value; client.PurgeDeletedSecret(secret.Name); #endregion }
private void BackupAndRestoreSync(string keyVaultUrl) { #region Snippet:SecretsSample2SecretClient var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); #endregion #region Snippet:SecretsSample2CreateSecret string secretName = $"StorageAccountPassword{Guid.NewGuid()}"; var secret = new KeyVaultSecret(secretName, "f4G34fMh8v"); secret.Properties.ExpiresOn = DateTimeOffset.Now.AddYears(1); KeyVaultSecret storedSecret = client.SetSecret(secret); #endregion #region Snippet:SecretsSample2BackupSecret string backupPath = Path.GetTempFileName(); byte[] secretBackup = client.BackupSecret(secretName); File.WriteAllBytes(backupPath, secretBackup); #endregion // The storage account secret is no longer in use so you delete it. DeleteSecretOperation operation = client.StartDeleteSecret(secretName); // Before it can be purged, you need to wait until the secret is fully deleted. while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } // 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. client.PurgeDeletedSecret(secretName); #region Snippet:SecretsSample2RestoreSecret byte[] secretBackupToRestore = File.ReadAllBytes(backupPath); SecretProperties restoreSecret = client.RestoreSecretBackup(secretBackupToRestore); #endregion AssertSecretsEqual(storedSecret.Properties, restoreSecret); }
public async Task StartDeleteSecret() { string secretName = Recording.GenerateId(); KeyVaultSecret secret = await Client.SetSecretAsync(secretName, "value"); RegisterForCleanup(secret.Name); DeleteSecretOperation deleteOperation = await Client.StartDeleteSecretAsync(secretName); DeletedSecret deletedSecret = deleteOperation.Value; AssertSecretPropertiesEqual(secret.Properties, deletedSecret.Properties); Assert.NotNull(deletedSecret.DeletedOn); Assert.NotNull(deletedSecret.ScheduledPurgeDate); Assert.ThrowsAsync <RequestFailedException>(() => Client.GetSecretAsync(secretName)); }
public async Task OperationUpdateStatus() { // create a client SecretClient client = new SecretClient(new Uri("http://example.com"), new DefaultAzureCredential()); #region Snippet:OperationUpdateStatus // Start the operation DeleteSecretOperation operation = await client.StartDeleteSecretAsync("SecretName"); await operation.UpdateStatusAsync(); // HasCompleted indicates if operation has completed successfully or otherwise Console.WriteLine(operation.HasCompleted); // HasValue indicated is operation Value is available, for some operations it can return true even when operation // hasn't completed yet. Console.WriteLine(operation.HasValue); #endregion }
public void DeleteAndPurgeSecret() { #region Snippet:DeleteAndPurgeSecret DeleteSecretOperation operation = client.StartDeleteSecret("secret-name"); // You only need to wait for completion if you want to purge or recover the secret. // You should call `UpdateStatus` in another thread or after doing additional work like pumping messages. while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } DeletedSecret secret = operation.Value; client.PurgeDeletedSecret(secret.Name); #endregion }
public async Task GetDeletedSecret() { string secretName = Recording.GenerateId(); KeyVaultSecret secret = await Client.SetSecretAsync(secretName, "value"); RegisterForCleanup(secret.Name); DeleteSecretOperation deleteOperation = await Client.StartDeleteSecretAsync(secretName); DeletedSecret deletedSecret = deleteOperation.Value; await WaitForDeletedSecret(secretName); DeletedSecret polledSecret = await Client.GetDeletedSecretAsync(secretName); Assert.NotNull(deletedSecret.DeletedOn); Assert.NotNull(deletedSecret.RecoveryId); Assert.NotNull(deletedSecret.ScheduledPurgeDate); AssertSecretPropertiesEqual(deletedSecret.Properties, polledSecret.Properties); AssertSecretPropertiesEqual(secret.Properties, polledSecret.Properties); }
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 }
public void HelloWorldSync() { // 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 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 = $"BankAccountPassword-{Guid.NewGuid()}"; var secret = new KeyVaultSecret(secretName, "f4G34fMh8v") { Properties = { ExpiresOn = DateTimeOffset.Now.AddYears(1) } }; client.SetSecret(secret); // Let's Get the bank secret from the key vault. KeyVaultSecret bankSecret = client.GetSecret(secretName); Debug.WriteLine($"Secret is returned with name {bankSecret.Name} and value {bankSecret.Value}"); // After one year, the bank account is still active, we need to update the expiry time of the secret. // The update method can be used to update the expiry attribute of the secret. It cannot be used to update // the value of the secret. bankSecret.Properties.ExpiresOn = bankSecret.Properties.ExpiresOn.Value.AddYears(1); SecretProperties updatedSecret = client.UpdateSecretProperties(bankSecret.Properties); Debug.WriteLine($"Secret's updated expiry time is {updatedSecret.ExpiresOn}"); // Bank forced a password update for security purposes. Let's change the value of the secret in the key vault. // To achieve this, we need to create a new version of the secret in the key vault. The update operation cannot // change the value of the secret. var secretNewValue = new KeyVaultSecret(secretName, "bhjd4DDgsa") { Properties = { ExpiresOn = DateTimeOffset.Now.AddYears(1) } }; client.SetSecret(secretNewValue); // The bank account was closed. You need to delete its credentials from the key vault. DeleteSecretOperation operation = client.StartDeleteSecret(secretName); // To ensure the secret is deleted on server before we try to purge it. while (!operation.HasCompleted) { Thread.Sleep(2000); operation.UpdateStatus(); } // If the keyvault is soft-delete enabled, then for permanent deletion, deleted secret needs to be purged. client.PurgeDeletedSecret(secretName); }
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)); }
private void GetSecretsSync(string keyVaultUrl) { #region Snippet:SecretsSample3SecretClient var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); #endregion #region Snippet:SecretsSample3CreateSecret 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); client.SetSecret(bankSecret); client.SetSecret(storageSecret); #endregion #region Snippet:SecretsSample3ListSecrets Dictionary <string, string> secretValues = new Dictionary <string, string>(); IEnumerable <SecretProperties> secrets = client.GetPropertiesOfSecrets(); foreach (SecretProperties secret in secrets) { KeyVaultSecret secretWithValue = client.GetSecret(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); } #endregion #region Snippet:SecretsSample3ListSecretVersions string newBankSecretPassword = "******"; IEnumerable <SecretProperties> secretVersions = client.GetPropertiesOfSecretVersions(bankSecretName); foreach (SecretProperties secret in secretVersions) { KeyVaultSecret oldBankSecret = client.GetSecret(secret.Name, secret.Version); if (newBankSecretPassword == oldBankSecret.Value) { throw new InvalidOperationException($"Secret {secret.Name} reuses a password"); } } client.SetSecret(bankSecretName, newBankSecretPassword); #endregion #region Snippet:SecretsSample3DeleteSecrets DeleteSecretOperation bankSecretOperation = client.StartDeleteSecret(bankSecretName); DeleteSecretOperation storageSecretOperation = client.StartDeleteSecret(storageSecretName); while (!bankSecretOperation.HasCompleted || !storageSecretOperation.HasCompleted) { Thread.Sleep(2000); bankSecretOperation.UpdateStatus(); storageSecretOperation.UpdateStatus(); } #endregion #region Snippet:SecretsSample3ListDeletedSecrets IEnumerable <DeletedSecret> secretsDeleted = client.GetDeletedSecrets(); foreach (DeletedSecret secret in secretsDeleted) { Debug.WriteLine($"Deleted secret's recovery Id {secret.RecoveryId}"); } #endregion // If the Key Vault is soft delete-enabled, then for permanent deletion, deleted secret needs to be purged. client.PurgeDeletedSecret(bankSecretName); client.PurgeDeletedSecret(storageSecretName); }
public void GetSecretsSync() { // Environment variable with the Key Vault endpoint. string keyVaultUrl = TestEnvironment.KeyVaultUrl; #region Snippet:SecretsSample3SecretClient var client = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential()); #endregion #region Snippet:SecretsSample3CreateSecret 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); client.SetSecret(bankSecret); client.SetSecret(storageSecret); #endregion #region Snippet:SecretsSample3ListSecrets Dictionary <string, string> secretValues = new Dictionary <string, string>(); IEnumerable <SecretProperties> secrets = client.GetPropertiesOfSecrets(); foreach (SecretProperties secret in secrets) { /*@@*/ if (secret.Managed) { continue; } // Getting a disabled secret will fail, so skip disabled secrets. if (!secret.Enabled.GetValueOrDefault()) { continue; } KeyVaultSecret secretWithValue = client.GetSecret(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); } } #endregion #region Snippet:SecretsSample3ListSecretVersions string newBankSecretPassword = "******"; IEnumerable <SecretProperties> secretVersions = client.GetPropertiesOfSecretVersions(bankSecretName); foreach (SecretProperties secret in secretVersions) { // Secret versions may also be disabled if compromised and new versions generated, so skip disabled versions, too. if (!secret.Enabled.GetValueOrDefault()) { continue; } KeyVaultSecret oldBankSecret = client.GetSecret(secret.Name, secret.Version); if (newBankSecretPassword == oldBankSecret.Value) { Debug.WriteLine($"Secret {secret.Name} reuses a password"); } } client.SetSecret(bankSecretName, newBankSecretPassword); #endregion #region Snippet:SecretsSample3DeleteSecrets DeleteSecretOperation bankSecretOperation = client.StartDeleteSecret(bankSecretName); DeleteSecretOperation storageSecretOperation = client.StartDeleteSecret(storageSecretName); // You only need to wait for completion if you want to purge or recover the secret. while (!bankSecretOperation.HasCompleted || !storageSecretOperation.HasCompleted) { Thread.Sleep(2000); bankSecretOperation.UpdateStatus(); storageSecretOperation.UpdateStatus(); } #endregion #region Snippet:SecretsSample3ListDeletedSecrets IEnumerable <DeletedSecret> secretsDeleted = client.GetDeletedSecrets(); foreach (DeletedSecret secret in secretsDeleted) { Debug.WriteLine($"Deleted secret's recovery Id {secret.RecoveryId}"); } #endregion // If the Key Vault is soft delete-enabled, then for permanent deletion, deleted secret needs to be purged. client.PurgeDeletedSecret(bankSecretName); client.PurgeDeletedSecret(storageSecretName); }
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 SetSecretWithExtendedProps() { string secretName = Recording.GenerateId(); IResolveConstraint createdUpdatedConstraint = Is.EqualTo(DateTimeOffset.FromUnixTimeSeconds(1565114301)); KeyVaultSecret setResult = null; try { var exp = new DateTimeOffset(new DateTime(637027248120000000, DateTimeKind.Utc)); DateTimeOffset nbf = exp.AddDays(-30); var secret = new KeyVaultSecret(secretName, "CrudWithExtendedPropsValue1") { Properties = { ContentType = "password", NotBefore = nbf, ExpiresOn = exp, Tags = { { "tag1", "value1" }, { "tag2", "value2" } }, }, }; setResult = await Client.SetSecretAsync(secret); if (Mode != RecordedTestMode.Playback) { DateTimeOffset now = DateTimeOffset.UtcNow; createdUpdatedConstraint = Is.InRange(now.AddMinutes(-5), now.AddMinutes(5)); } RegisterForCleanup(secret.Name); Assert.IsNotEmpty(setResult.Properties.Version); Assert.AreEqual("password", setResult.Properties.ContentType); Assert.AreEqual(nbf, setResult.Properties.NotBefore); Assert.AreEqual(exp, setResult.Properties.ExpiresOn); Assert.AreEqual(2, setResult.Properties.Tags.Count); Assert.AreEqual("value1", setResult.Properties.Tags["tag1"]); Assert.AreEqual("value2", setResult.Properties.Tags["tag2"]); Assert.AreEqual(secretName, setResult.Name); Assert.AreEqual("CrudWithExtendedPropsValue1", setResult.Value); Assert.AreEqual(VaultUri, setResult.Properties.VaultUri); Assert.AreEqual("Recoverable+Purgeable", setResult.Properties.RecoveryLevel); Assert.That(setResult.Properties.CreatedOn, createdUpdatedConstraint); Assert.That(setResult.Properties.UpdatedOn, createdUpdatedConstraint); KeyVaultSecret getResult = await Client.GetSecretAsync(secretName); AssertSecretsEqual(setResult, getResult); } finally { DeleteSecretOperation deleteOperation = await Client.StartDeleteSecretAsync(secretName); DeletedSecret deleteResult = deleteOperation.Value; AssertSecretPropertiesEqual(setResult.Properties, deleteResult.Properties); } }
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 } }
/// <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; } }
/// <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; } }
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)); }