Menu Close

How to store app secrets in ASP.NET Core using Secret Manager

In this article, we will learn How to store app secrets in ASP.Net Core using Secret Manager. We describe how to manage sensitive data on a development machine for an ASP.NET Core project. Passwords and other sensitive data should never be stored in source code. Development and testing should not use production secrets. Secrets should not be distributed with the app. Production secrets should instead be accessed through a regulated mechanism such as environment variables or Azure Key Vault. The Azure Key Vault configuration provider allows you to store and safeguard Azure test and production secrets. Please read my previous article on How to use Azure Key Vault in ASP.Net Core.

Find the Source Code in this GitHub link.

This article is for anyone who is new to ASP.NET Core or is currently storing your secrets in config files that you may or may not check in by accident. Keep secrets separate, use the Secret management tool in development mode, and consider services like Azure KeyVault for production.

Why is the Secret manager required?

Let’s discuss app secrets and configuration, as well as why we need a solution to handle them. There are several reasons why this needs to be managed, preferably via a tool:

  • Separate config/secrets from source code: Passwords, API keys, and other secrets may be included in configuration strings. Your system may be vulnerable if this information is exposed. You should avoid storing any data in source code because your source code will most likely wind up in a GitHub or similar repository. Even though it’s a private repository, it could be compromised. It’s best to keep this somewhere else.
  • Values differ in different settings: The values you use for DEV, Staging, and Prod should differ when connecting to a database or API. You must recognize what is different so that you can break this out as settings that must be modified per environment.
  • Different OS: Because operating systems differ, you may believe that converting all secrets to environment variables is sufficient. However, if you have a lot of settings, you may need to structure it in a hierarchy, such as api:apitype>:apikey>. One problem though, : isn’t supported on all OSs but other characters are like _. The point is that you want an abstraction layer to organize your secrets/config.

What happens when we use environmental variables

  • Environment variables are generally stored in plain, unencrypted text. If the machine or process is compromised, environment variables can be accessed by untrusted parties. Additional measures to prevent disclosure of user secrets may be required.
  • Also the : separator doesn’t work with environment variable hierarchical keys on all platforms. __, the double underscore, is:

Here in this post, we are discussing how to use the Secret Manager tool to store our secret Key and Values.

What is a Secret Manager and How does it work?

The Secret Manager tool hides the implementation details including where and how values are saved. You can use the tool without knowing the details of its implementation. The values are saved in a JSON file in the user profile folder of the local machine.

When you install.NET Core, you get a built-in tool for managing configuration and secrets. It addresses several of the issues raised in the previous section. However, there are a few things you should be aware of before we proceed:

  • The tool is for local dev: The secret manager tool is great for local development but that’s where it should stay.
  • Environment variables are not safe: Your machine might be compromised and Environment Variables are plain text and not encrypted. So even though it’s tempting to rely on Environment Variables and store those in AppSetting in Azure you want to look into more safe ways of handling secrets like KeyVault.

The secret manager tool is a command-line utility for storing your secrets in a JSON file. When you use the tool for a specific project, it generates a Secret Id and saves a JSON file in the following OS-dependent location:

File System Path:

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

File system path:

~/.microsoft/usersecrets/<user_secrets_id>/secrets.json

Steps to use Manage Secrets

  • Initialization/Setup of the Project: This is how you generate an ID and create a file that will contain your secrets.
  • Setting a Secret Value: This is about setting a value, either from a terminal or from code.
  • Accessing a Secret Value: This can be done from both the terminal and the code.
  • Removing a Secret Value: It’s good to know how to remove a value when you no longer need it. It can be removed from both the terminal and code.

Initialization/Setup of the Project

Let’s create an ASP.Net Core Web API Project, you can follow how we can create Building CRUD REST APIs in ASP.Net Core 7.0 with EF. We can also create an ASP.Net Core Project using the command line like below,

dotnet new webapi --name AppSecrets.API

Type the below command to initiate the user secrets.

dotnet user-secrets init

The terminal should give you an output like below,

Set UserSecretsId to '<secret-id>' for MSBuild project '/path/to/your/project/project.csproj'
User Secrets

Open up your project file that ends in .csproj by right clock on the project. Locate an entry under PropertyGroup looking like below, This UserSecretsId is how the secrets JSON file is connected to your app.

<UserSecretsId>secret-id</UserSecretsId>
User Secrets Id

Setting a Secret Value

Create an app secret that consists of a key and its value. The secret is associated with the UserSecretsId value of the project. For example, from the directory containing the project file, execute the following command:

dotnet user-secrets set "AppSecretsKey" "Rnd$321!76WqA5rT"

We can create a group of secrets using the below command.

dotnet user-secrets set "ApiHost:Url" "https://jayanttripathy.com/"
dotnet user-secrets set "ApiHost:ApiKey" "3312#"

To see the list of secrets use the command like below.

dotnet user-secrets list

List your secret content:

AppSecretsKey = Rnd$321!76WqA5rT
ApiHost:Url = https://jayanttripathy.com/
ApiHost:ApiKey = 3312#
User Secrets creation

Accessing a Secret Value

The Configuration API will help us retrieve our secrets in source code. It’s a powerful API that is capable of reading data from various sources like appsettings.json, environment variables, KeyVault, Command-line, and much more, with the help of dedicated providers that can be added at startup. It’s worth stressing this API helps us only in development mode when it comes to reading secrets.

The secret management tool is only meant for development so that works for us.

To access the secret values we need to follow the below configurations.

Creating the Models

Let’s create the Model class according to our secret files.

namespace AppSecrets.API.Models
{
    public class AppConfiguration
    {
        public string ApiKey { get; set; }
        public ApiHost ApiHost { get; set; }
    }
    public class ApiHost
    {
        public string Url { get; set; }
        public string ApiKey { get; set; }
    }
}

Add the Config information to get the Secret file in Program.cs

var config = new AppConfiguration();
config.ApiKey = builder.Configuration["AppSecretsKey"];

var apiHostConfig = builder.Configuration.GetSection("ApiHost")
                          .Get<ApiHost>();
config.ApiHost = apiHostConfig;

builder.Services.AddSingleton<AppConfiguration>(config);
  • Line #2- Here it reads the AppSecrets Key from the configuration.
  • The GetSection() method allows us to grab a namespace and then map everything on that namespace and map it into a type. This is great now we can have dedicated parts of our secrets mapped to dedicated configuration classes, It reads the APIHost details associated with URL and ApiKey.
  • Line #8- Added the configuration model to use the dependency.

Getting the value in Controller by following the below steps

Create a controller named as AppSecretController and here we inject the AppConfiguration model to access the secret Key information.

[Route("api/[controller]")]
    [ApiController]
    public class AppSecretController : ControllerBase
    {
        private readonly AppConfiguration _config;

        public AppSecretController(AppConfiguration config)
        {
            this._config = config;
        }

        [HttpGet]
        public IActionResult Get()
        {
            return Ok(this._config);
        }
    }

Run the application and you can see on the below screen the Secret information is displayed in JSON format.

User Secrets JSON in Swagger

How to see the secret.json file in Visual Studio

To see the secret.json file, Right click on Project, and click on Manage User Secrets, it navigates to your secret.json file. You can find the secret keys available that we have created.

User Secrets- manage user secrets
User-Secrets-secret.json

Remove a single secret

To remove the single secret we can follow the below command,

dotnet user-secrets remove "--secretname--"

Let’s in our case the secret.json contains the below structure,

{
  "AppSecretsKey": "Rnd$321!76WqA5rT",
  "ApiHost:Url": "https://jayanttripathy.com/",
  "ApiHost:ApiKey": "3312#"
}

Here we may remove “ApiHost: ApiKey”, let’s see how we can do that. Type the command hit enter button and it removes the key that you want.

dotnet user-secrets remove "ApiHost:ApiKey"

User Secrets remove

Remove all secrets

Following the below command we can remove all the secret keys one at a time.

dotnet user-secrets clear
User Secrets remove all

Find the Source Code in this GitHub link.

That’s it for the article, How to store app secrets in ASP.NET Core using Secret Manager. đŸ™‚

Conclusion

In this article, we discussed How to store app secrets in ASP.Net Core using Secret Manager. We spoke about why it’s a poor idea to include secrets in your source code because you could accidentally check it in. We also discussed how the secret manager tool might help you maintain track of your secrets while developing. Then we demonstrated how to manage secrets and hence cover:

  • Adding secrets
  • Reading secrets from the command line and from code
  • Remove secrets

Leave behind your valuable queries and suggestions in the comment section below. Also, if you think this article helps you, do not forget to share this with your developer community. Happy Coding đŸ™‚

Related Articles

SUPPORT ME

Buy Me A Coffee

Leave a Reply

Your email address will not be published. Required fields are marked *