Skip to content

Instantly share code, notes, and snippets.

Last active February 16, 2021 22:24
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
KeyVault Secrets Rotation Management
dotnet add package Azure.Security.KeyVault.Secrets --version 4.2.0-beta.4
dotnet add package Azure.Identity --version 1.4.0-beta.3
dotnet add package System.Linq.Async --version 4.1.1
func new --name BulkDisableSecretsHttpTrigger --template HttpTrigger --language C#
public static class BulkDisableSecretsHttpTrigger
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "secrets/all/disable")] HttpRequest req,
ILogger log)
// Get the KeyVault URI
var uri = Environment.GetEnvironmentVariable("KeyVault__Uri");
// Get the tenant ID where the KeyVault lives
var tenantId = Environment.GetEnvironmentVariable("KeyVault__TenantId");
// Set the tenant ID, in case your account has multiple tenants logged in
var options = new DefaultAzureCredentialOptions()
SharedTokenCacheTenantId = tenantId,
VisualStudioTenantId = tenantId,
VisualStudioCodeTenantId = tenantId,
var client = new SecretClient(new Uri(uri), new DefaultAzureCredential(options));
// Get the all secrets
var secrets = await client.GetPropertiesOfSecretsAsync()
var utcNow = DateTimeOffset.UtcNow;
var results = new Dictionary<string, object>();
foreach (var secret in secrets)
// Get the all versions of the given secret
// Filter only enabled versions
// Sort by the created date in a reverse order
var versions = await client.GetPropertiesOfSecretVersionsAsync(secret.Name)
.WhereAwait(p => new ValueTask<bool>(p.Enabled.GetValueOrDefault() == true))
.OrderByDescendingAwait(p => new ValueTask<DateTimeOffset>(p.CreatedOn.GetValueOrDefault()))
// Do nothing if there is no version enabled
if (!versions.Any())
// Do nothing if there is only one version enabled
if (versions.Count < 2)
// Do nothing if the latest version was generated less than a day ago
if (versions.First().CreatedOn.GetValueOrDefault() <= utcNow.AddDays(-1))
// Disable all versions except the first (latest) one
var candidates = versions.Skip(1).ToList();
var result = new List<SecretProperties>() { versions.First() };
foreach (var candidate in candidates)
candidate.Enabled = false;
var response = await client.UpdateSecretPropertiesAsync(candidate).ConfigureAwait(false);
results.Add(secret.Name, result);
var res = new ContentResult()
Content = JsonConvert.SerializeObject(results, Formatting.Indented),
ContentType = "application/json",
return res;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment