.NET Core local development — How to store secrets?

Rocco Scaramuzzi
rocco.tech
Published in
3 min readJun 20, 2020

I have seen a lot of projects where database connections strings, service bus, blob storage access keys are stored in the appsettings.json for local development purpose and all this breaches basic security best practices.

appsettings.json example

Why is it a problem?

The appsettings.json will be stored in version control and this open possible security breaches:

  • Anyone who has access or clone the repository will have access to those secrets.
  • Version control is designed to preserve history. So passwords will still be retrievable, even if we remove the password from the current version.
  • Having sensitive data in the source means that we need to take extra care when sharing the code.

A possible mitigation adopted by several developers is to create appsettings.Development.json but this is not any better unless this file is being added to the .gitignore file. I have seen appsettings.Development.json containing Azure resources secretes and being pushed in git:-( .

Solution — Secret Manager Tool

The solution consists to have our appsettings.json containing all the possible secrets as empty strings and then using the Secret Manager tool to store sensitive data.

appsettings.json with no secrets

The Secret Manager tool abstracts the implementation details, in terms of how and where to store values. The values are stored in a JSON configuration file in a system-protected user profile folder on the local machine:

%APPDATA%\Microsoft\UserSecrets\<user_secrets_id>\secrets.json

In this way the app secrets are not checked in the source control.

Let’s see how to use Secret Manager to populate our two secrets. One way is to use .NET Core SDK commands, by executing the following steps:

  1. initialize:
dotnet user-secrets init

2. set first secrets:

dotnet user-secrets set "ConnectionStrings:DefaultConnection" "Server=tcp:mydb.database.windows.net,1433;Initial Catalog=mydb;Persist Security Info=False;User ID=myuser;Password=mypassword;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;"

3. set second secrets:

dotnet user-secrets set "AzureStorage:ConnectionString" "DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=myKey+xxxxxxxx+yyyyyyyyy==;EndpointSuffix=core.windows.net"

An alternative to the command line is to use directly Visual Studio, by right-clicking on the project and then selecting “Manage User Secrets”:

Set Secrets via Visual Studio

Conclusion

  • Please note that the secrets will be loaded by the secret manager if your app is running on your local with ASPNETCORE_ENVIRONMENT = Development.
  • About production, the secrets should not be deployed with the app but instead those should be set as environment variables or even better via Azure Key Vault. This is a common best practice, accordingly to the 12-factor guidelines https://12factor.net/config.

Resources:

--

--

Rocco Scaramuzzi
rocco.tech

Tech Lead, Technical Architect, Coder, Senior Software Engineer