User Secrets in a .NET Core Web App
Time to read: 5 minutes
Ever had that sinking moment of realisation when you push your secrets to GitHub? I have and I doubt I’m the only one.
There are many reasons why you wouldn’t want your sensitive configurations shared and I’m not just talking about on GitHub. Members of a development team may not use the same test databases or connection strings. Maybe the dev team only has access to the test keys for apps such as Twitter but the live keys are squirrelled away in Azure.
A common way to deal with sensitive data in an app is by using Environment Variables. With the arrival of .NET Core we now have a tidy way of managing configuration and sensitive data in the form of User Secrets, which can be managed by the Secrets Manager Tool (SMT) from the command line. User Secrets are stored outside of the project tree in a JSON configuration file in the user profile directory and are therefore outside of source control.
See this post to add User Secrets in a console app.
I have created a solution on GitHub so feel free to follow along with the completed project or have a go at implementing it into your own .NET Core API or MVC web application with your own secrets.
Adding User Secrets to your project
On Windows with Visual Studio 2017
If you are using Visual Studio on Windows and have a web project, then adding User Secrets takes only a few clicks. Right click on the project and select Manage User Secrets.
Clicking this will do a couple of things; it will open the secrets.json
file in Visual Studio where you can add your secrets and it will add the <userSecretsId>
to the .csproj
file.
It’s also a good idea to add the SMT to the .csproj
file which will enable you to update the User Secrets from the command line.
Update: As of .NET Core 2.1, the SMT will be included on the dotnet cli, so you won’t need to add it separately.
Below is an example of what you may wish to add to your User Secrets. It includes two ways of writing a json object and a simple key/value pair. Not everything needs to be secret so don’t get carried away. I would normally store anything that I wouldn’t want in a public repo in the secrets.json
file.
SMT will handle the storage of your secrets and place them in %APPDATA%\Microsoft\UserSecrets\<guid>\secrets.json
without you really having to worry about the implementation.
On Linux, macOS or alternative IDE
If you are not using Visual Studio 2017 or you are working in Linux or macOS, the option to Manage User Secrets will not be available to you via a right-click. In this case you will need to add the secrets manually.
As I mentioned, User Secrets are stored outside of your project tree and on Linux and macOs are stored in ~/.microsoft/usersecrets/<guid>/secrets.json
.
If the .microsoft
folder is not present on Linux or macOS, then you’ll need to create it. Remember it may be hidden, so check for that before creating a new file. You can list hidden as well as non hidden files with the ls -la
command in your terminal. If you do need to create a new .microsoft
folder you can do so by running the following command in your terminal:
You will need to create the <userSecretsId>
GUID and can do so using a GUID generator such as this one.
Add the tag to the .csproj
underneath the <TargetFramework>
tag and the SMT in an <ItemGroup>
:
Now we can create and update the User Secrets from the command line, this goes for any project type in any OS. To do this, navigate to the root of the project, where the .csproj
file is, and enter the following command:
If you already have a value stored in your environment variables, you can replace ACCOUNT_SID
with the name of your environment variable prefixed with $
to read it and save it to the User Secrets. For example $TWILIO_ACCOUNT_SID
.
User Secrets can be shared across multiple projects via their GUID or even a different set of User Secrets for each branch of your solution, making maintenance of shared data that little bit easier.
It is worth noting that User Secrets are not encrypted and are only available during development.
Mapping User Secrets to a model
The best way to consume User Secrets, in my opinion, is to map them to a model. This will give type safety and prevent any errors from misspelt string names. It also makes your code that little bit more testable.
There are a few steps to do this, the first being to add the secrets to the appsettings.json
, found in the root of your project. This will need to correlate closely to your secrets.json
file, only with sensitive data removed. I usually add a note to myself about where I have actually set my sensitive data as in the following example:
Next we need to create the C#
model that we want to map the secrets to. To keep my solution organised I tend to add a Configuration
folder to my Models
folder whether that be in the same project or in a dedicated models project being referenced. Make sure that the names in the secrets.json
file are the same in both the appsettings.json
file and the C#
models.
I will repeat this process for each json
object or key/value pair I have created in my secrets.json
.
Adding the Configuration
We will need to install a few nuget packages to the .csproj
of our web app.
Restore your nuget packages from within Visual Studio, by right clicking on the solution and selecting Restore NuGet Packages, or from the command line by using dotnet restore
. Now that we have the models, we can bind the values. This is done in the Startup.cs
file.
Using your mapped secrets
Now that our secrets have been mapped, we can use .NET Core’s built in dependency injection to inject the secrets into the constructors of classes and services. This is done via the IOptions<>
interface. For more information on Dependency Injection in .NET Core have a look at this post from Microsoft.
Overwriting AppSettings on Azure
If you’re deploying a web app to Azure, it’s relatively straightforward to add your secrets, requiring only a single step. From within the portal, select your web app and then scroll down the menu until you find application settings
.
Then enter your secrets, matching case, as key/value pairs.
Summary
That’s it! You can now extract your configuration and sensitive data from your code. This affords you and your team more flexibility, security and testability.
Remember that User Secrets are not encrypted and can only be used within the development environment.
If you want to review the code in its entirety checkout out the GitHub repo, where both the WebApp and the Console App can be found. Drop a comment below or tweet me at @LaylaCodesIt if you have any questions. I can’t wait to see what you build!
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.