Safely Storing Sensitive Configuration Data in .NET Core
There could be a situation where the application will use some sensitive data such as Payment Gateway live credentials and client don’t want to expose the data to any of their developers and staff about it.
To fulfill this requirement from the client, the .NET core provides different methodologies to store the configuration data and following are those
Method-1: Using Environment level configuration JSON files
.NET Core supports to configure by different Environments like Development, Production, and Staging. By default, when we create a .NET Core application, appsettings.json file will be created and configured while initializing the host environment. This JSON file can be used to provide different configuration values which application can use at runtime. Also, we can create separate appsettings JSON files Environment wise by adding environment name to the file name. For example, the Production environment will be named as appsettings.Production.json.
The same environment name should be assigned for ASPNETCORE_ENVIRONMENT variable either by using properties window by right-clicking on the project -> Properties -> Debug window as follows
Or, we can even add the same details in launchSettings.json file as follows
Now, let’s try to read data from Production appsettings.json file.
When we run the application in production environment obviously we use to get the database connection string with ProdDB server.
But, here we are not getting any privacy for the connection string as everyone from developers as well as staff can see this information from this JSON file.
So, this method doesn’t suit for maintaining sensitive configuration data in appsettings JSON files.
Method-2: Use Environment Variables
This is simple, we just avoiding to provide connection string in the appsettings.json and providing the same in Environment variables as we done in the above method for ASPNETCORE_ENVIRONMENT as follows.
When we run the application, the connection string in the appsettings.json will be overridden by this environment variable and we can see the value which was set here.
Everything looks good as the connection string will be set in project level environment variable and so we are avoiding maintaining sensitive data in JSON files. But, still, once we save this properties page the same can be seen in the launchSettings.json file as .NET Core will maintain all profile level information in JSON file as below
Still, the data is not safe and can read from this JSON file. So, method 2 also not suitable for storing sensitive information.
Method-3: Using System Environment Variables
This method is almost same as above method but, here we create a connection string variable in OS level Environment variables. As we are not setting connection string at applications, we don’t see the information which we created in system level environment variables and surely this could be the best method for storing sensitive information. As we set all sensitive information on a production server and we don’t have any scope to see these settings by any developers or second level staff.
How can we set System level Environment variables?
We need to go My Computer -> Change Settings a system properties window will be open, where we need to go Advanced tab as follows
Click on Environment Variables button where we can set the system level configuration data as follows where we set our connection string.
This setting will be at a server level, so, there is no chance to see this configuration data except the people who have permissions.
Now, how our application can read this information? In .NET Core, we have a method called AddEnvironmentVariables() which we read all system level environment variables to the configuration object.
Earlier versions of .NET Core I.e., before .NET Core 2.0, we need to explicity call this method in a constructor of Startup file as follows
Configuration = new ConfigurationBuilder() .SetBasePath(hostingEnvironment.ContentRootPath) .AddJsonFile("appsettings.json", true) .AddEnvironmentVariables() .Build();
But in .NET Core 2.0, it will be set by default when the ASP.NET Host is initialized in program class.
Note: Make sure to close and open the application after adding a new variable in system level environment variables. As these variables will be added to an IConfiguration object while initializing host.
Now, when we run the application we can see the settings what we set in the system level Environment variables assigned accordingly as below
string connectionString = Configuration["ConnectionStrings:DefaultConnection"];
If you want to store any sensitive configuration data, System-level Environment variables are the best place to have.
Hope this article helps you
Happy Coding 🙂