Keep Your Source Secure: Stop Committing Sensitive Information to Git


Do you have your security engineer running behind you to remove secrets off git? Or keep getting alerts in gitleaks or in your CI security scanning tool that someone inadvertently committed a secret in git? Developers might forget to sanitize the appsettings.json
before committing, so the best way is to never give the secrets to the developers in the first place, and provide a way for them to debug code locally without needing all the secrets. Let’s look at how we can use KeyVault even for local debugging, and avoid developers committing secrets.
The code for this is available in my github repo.
To summarize the idea:
Create one KeyVault per environment.
Give necessary permissions to the developers (via AD Group) to read secrets on the keyvault via Microsoft Entra ID, only for certain environments like Dev.
Make sure the developers are signed in to Visual Studio with their Entra ID.
To debug in different environments, developers will change the KV url as needed, and nothing else.
First off, read the appsettings.json
- done here explicitly in case you need control over which files are read:
public static IConfigurationBuilder LoadConfigurations(this IConfigurationBuilder builder)
{
builder.SetBasePath(AppContext.BaseDirectory)
.AddJsonFile("appsettings.json", false)
.EnableKeyVault();
return builder;
}
Then override the values in appsettings.json with values available in the keyvault. If any the secret key is not there in KV, the value in appsettings.json is retained. The url of the keyvault is also read from appsettings :)
appsettings.json
{
"App": {
"KeyVaultUrl": "https://your-own-keyvault.vault.azure.net/" //Use env specific keyvault url
},
"ConnectionStrings": {
"AppDatabase": "",
"ServiceBus": "",
"FileStorage": ""
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
And the core EnableKeyVault extension method:
public static void EnableKeyVault(this IConfigurationBuilder config)
{
// Load environment variables
config.AddEnvironmentVariables();
IConfigurationRoot builtConfig = config.Build();
string? keyVaultUrlBase = builtConfig[$"App:KeyVaultUrl"]; // Read the url of KV from appsettings.json
if (string.IsNullOrEmpty(keyVaultUrlBase))
{
// If you do not want to use the values in KeyVault, make the kv url empty and put the values specifically in appsettings.json
// But do not commit these appsettings.json changes. - Throw exception if you do not want to give this option
// to developers
return;
}
// Use default azure credential to authenticate to key vault,
// we need to turn off some of the default credential providers as they are not
// available during local development.
// Similary, VS credential providers need to be turned off when deploying in AKS
// NOTE: This requires the developer to perform `az login` in the terminal first or login to Visual Studio.
// https://learn.microsoft.com/en-us/dotnet/azure/sdk/authentication/credential-chains?tabs=dac#defaultazurecredential-overview
bool isLocalDevelopment = builtConfig["ASPNETCORE_ENVIRONMENT"] == "Development";
DefaultAzureCredentialOptions credOptions = new()
{
ExcludeEnvironmentCredential = isLocalDevelopment,
ExcludeWorkloadIdentityCredential = isLocalDevelopment,
ExcludeManagedIdentityCredential = isLocalDevelopment,
ExcludeVisualStudioCredential = !isLocalDevelopment,
ExcludeVisualStudioCodeCredential = !isLocalDevelopment
};
_ = config.AddAzureKeyVault(new Uri(keyVaultUrlBase), new DefaultAzureCredential(credOptions));
}
This works in Windows, Linux and Mac.
The last credOptions setup is for the same code to work with Workload Identity or Managed Identity in a deployed environment. The same needs to be turned off for local development, and VS/VSCode credential need to be turned off in deployed environment.
Cheers!
Subscribe to my newsletter
Read articles from Narayana Rengaswamy directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
