KeyVault Secrets Rotation Management
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Microsoft.KeyVault(SecretUri=https://<keyvault_name>.vault.azure.net/secrets/<secret_name>) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add package Azure.Security.KeyVault.Secrets --version 4.2.0-beta.4 | |
dotnet add package Azure.Identity --version 1.4.0-beta.3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dotnet add package System.Linq.Async --version 4.1.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func new --name BulkDisableSecretsHttpTrigger --template HttpTrigger --language C# |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class BulkDisableSecretsHttpTrigger | |
{ | |
[FunctionName("BulkDisableSecretsHttpTrigger")] | |
public static async Task<IActionResult> Run( | |
[HttpTrigger(AuthorizationLevel.Function, "POST", Route = "secrets/all/disable")] HttpRequest req, | |
ILogger log) | |
{ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Get the KeyVault URI | |
var uri = Environment.GetEnvironmentVariable("KeyVault__Uri"); | |
// Get the tenant ID where the KeyVault lives | |
var tenantId = Environment.GetEnvironmentVariable("KeyVault__TenantId"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Get the all secrets | |
var secrets = await client.GetPropertiesOfSecretsAsync() | |
.ToListAsync() | |
.ConfigureAwait(false); | |
var utcNow = DateTimeOffset.UtcNow; | |
var results = new Dictionary<string, object>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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())) | |
.ToListAsync() | |
.ConfigureAwait(false); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Do nothing if there is no version enabled | |
if (!versions.Any()) | |
{ | |
continue; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Do nothing if there is only one version enabled | |
if (versions.Count < 2) | |
{ | |
continue; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Do nothing if the latest version was generated less than a day ago | |
if (versions.First().CreatedOn.GetValueOrDefault() <= utcNow.AddDays(-1)) | |
{ | |
continue; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); | |
result.Add(response.Value); | |
} | |
results.Add(secret.Name, result); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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