# Prevent secrets from getting out with .NET Core

I was recently building out a .NET Core Console App and it had secrets such as my Bit.ly API key and Azure Storage Table DB Connection string (which also has my password). I got busy and forgot what I was doing and committed it to GitHub. That really sucks, but

# I had options, but didn't take them

So why didn't I use Azure Key Vault (opens new window) or Secret Manager (opens new window)

For Azure Key Vault, I felt there was some overhead (such as learning it) that I didn't want to pay. It also is a very cheap service, but I wanted FREE. Regarding Secret Manager, that information is always stored in the user profile directory such as %APPDATA%\microsoft\UserSecrets\<userSecretsId>\secrets.json for Windows or ~/.microsoft/usersecrets/<userSecretsId>/secrets.json for Mac/Linux. This means if other folks want to get your key store, they can target those directories b/c the JSON file is unencrypted. Not that my version is encrypted, it just isn't stored in the user profile directory.

# How I Prevent secrets from getting pushed to GitHub with .NET Core

Part 1:

  • I create a new .NET Core App in Visual Studio. (For example: A console app)
  • I add a file called appSecrets.json and define a couple of secrets that I don't want getting out. Such as my Bit.ly API key and Azure Table Storage Connection String.
{
  "ConnectionStrings": {
    "BitlyAPI": "A_BITLY_API_KEY",
    "StorageAccountAPI": "MY_STORAGE_ACCOUNT_KEY"
  }
}
1
2
3
4
5
6

Part 2:

  • Set the appSecrets.json file to Copy if newer inside of Visual Studio.

Part 3:

  • I add the following NuGet packages that allows us to easily read a local JSON file (such as our appSecrets.json) and extract key pieces of information:

  • Microsoft.Extensions.Configuration

  • Microsoft.Extensions.Configuration.FileExtensions

  • Microsoft.Extensions.Configuration.Json

Part 4:

  • I add the following code inside the Main method.
  • This uses ConfigurationBuilder and searches for the file.
var builder = new ConfigurationBuilder()
    .SetBasePath(Directory.GetCurrentDirectory())
    .AddJsonFile("appSecrets.json", optional: false, reloadOnChange: true);
IConfigurationRoot configuration = builder.Build();
1
2
3
4

You can now access the value of the string with the following :

configuration.GetConnectionString("StorageAccountAPI")
1

Part 5: VERY IMPORTANT

  • Set your /.gitignore to ignore the appSecrets.json that we added.
#### Ignore Visual Studio temporary files, build results, and
#### files generated by popular Visual Studio add-ons.

appSecrets.json
1
2
3
4

You can verify this file is ignored by looking for the red circle if using Visual Studio.