How to handle on sensitive configurations on a release with asp.net core? - iis

I am seeking the best way to handle configurations in my aspnet core applications. See below my scenario.
Currently I am using the TFS as a repository of code and as the
orchestrator of all my release definitions that goes to a webserver with IIS
I have a multitenant
application and my code currently stores in the applications
settings the configuration I have per client
appsetting.Client1.json
appsetting.Client2.json
ConnectionString is part of the variables that are stored in my appsettings.Client#.json
Now, a big problem I am seeing so far is that I am saving all configurations in my repository, and all developers have access to my PROD settings as well.(something I want to avoid, like the connectionString)
My solution so far to this problem is trying to save all sensitive configurations in the configuration variables of my IIS per client.
and avoid having them on the code directly and also as part of the configuration on the continuous integration process on the TFS, which should look only as an orchestrator. So the app should take every secret thing from IIS configuration. Which now take me to another doubt if I am doing the things right: I will not have the connectionString as a section anymore on my appSettings so I will not get them as I usually did configuration.GetConnectionString.
Should I need to consider a different approach with the resources I have?

In development, use user secrets. It's basically just JSON config, but it's stored outside your project in your user directory. That way, there's no chance of any secrets making it into your source control. You don't need to do anything special, as user secrets config is included by default. Just right-click on your project and choose "Manage User Secrets".
In production, you can use environment variables, Azure Key Vault, etc. Basically, just as with development, you want to keep the secrets external to your project and out of your source control.
Because all these settings are external, it's also a good idea to mock them up in something like appsettings.json. For example:
{
"ConnectionStrings": {
"MyConnectionString": "[CONNECTION STRING]"
}
}
Then, you actually specify the value in user secrets in development and environment variables, Azure Key Vault, etc. in production. Since appsettings.json is included first, the other config sources will override the placeholder(s) here. But, it serves to document your config, so other developers know what they need to provide.

Related

How we can store API keys encrypted inside .net core console application

I am working on a .NET core console application which integrates with 3rd party APIs. and to do the integration I need to pass the API keys inside the API requests. so my question is where/how I can store the API keys inside my console application? in regular .NET console application I use to store the API keys inside the app.config and encrypt the keys using Aspnet_regiis.. but not sure how i can do so inside .NET core console application?
You can consider...
Get separate keys issued for different environments (so that a compromised key can be expired/cancelled without affecting other environment/s).
Store keys encrypted - for example - in the operating system provided key store [https://learn.microsoft.com/en-us/dotnet/standard/security/cryptography-model]. (This just means that they are not "left lying around" for casual passers by.)
Remove the code for retrieval of keys from the console app, perhaps to a simple service or library to which code the regular developers do not have access. (A level of separation.)
To embed information within the application, consider resource files [https://learn.microsoft.com/en-us/dotnet/framework/resources/creating-resource-files-for-desktop-apps]
Bottom line: This question illustrates the raison d'ĂȘtre for public key (asymmetric) cryptography [https://en.wikipedia.org/wiki/Public-key_cryptography] but any app that handles a piece of information "decrypted in flow" makes that information vulnerable to everyone who has permission to work on (debug) the live app or poke around with diagnostic tools on the system. (If a person needs a key to open a door then you must give them a key with which to open it and can't then prevent dishonest misuse of that privilege.)
A little bit of paranoia is healthy but too much can be an obstacle to getting things done.
Security in Development
For local development, you can use the Secrets Manager Tool (used only in development, never in production). This tool allows you to store your sensitive data locally on your machine, outside the project tree.
This tool is not super secure, and the keys are not encrypted, but it provides an easy way to avoid storing secrets in your project config files and having to remember to add them to the source control ignore list.
Security in Production
A common way is to store secrets in an external vault.
If you are hosting your application on Azure, Azure also provides a more secure option: Azure Key Vault.
Key Vault is a cloud-hosted service for managing secrets, which will be accessible by the applications you authorize through an encrypted channel.
It is advisable not to store encrypted keys inside a .NET console application. It is more ideal to keep secrets separate, store them using the Secret management tool in dev mode, and look into services like Azure KeyVault for production as mentioned earlier.
See the link about app secrets and configuration and why we need a tool to manage it on https://dev.to/dotnet/how-to-store-app-secrets-for-your-asp-net-core-project-2j5b for detailed instructions on how to do this.

How to share application settings between app services in Azure?

I have several App Services in Azure: development, test, and production. I would like to share some application settings between them like variable sets in Octopus.
Let's say I have a key A which should be same in all App Services. I would like to set its value in one place but seems that I have to configure it to each App Service. When A is changed, I have to change it to everywhere instead of having one common place to change it. Is there some way to do this?
No built-in way, app settings are part of the App Service resource.
You will need to put the settings in a common database or file.
Azure Key Vault can be used for sensitive settings and table storage/blob storage works well for other settings. Azure SQL is also an option.
Your app will then need to load these settings at startup.
This is also a documented cloud design pattern: https://learn.microsoft.com/en-us/azure/architecture/patterns/external-configuration-store

Migrating to Azure Web Role - porting the web.config file

I am migrating an existing Web Application to a Web Role. Does this mean that the web.config will be ignored?
I have connection strings, provider details, and tons of other config items in the web.config. Do I have to attempt to port all of this to the Azure ServiceConfiguration.Production.cscfg file?
In development, the Compute Emulator will not be used (since it takes so long), so we will still need the web.config files.
It depends on your use-case.
The cscfg allows you to reconfigure your WebRoles once deployed without creating a new package and redeploying/upgrading/staging+swapping. I especially think of scenarios where continuous integration is used and release procedures are no longer trivial.
If this scenario is not relevant you could just stick with the web.config and build and deploy new packages on configuration changes.
You could also selectively move items you assume that will regularly change in order to benefit from the configurability without having the effort of migrating everything.
I have used wrapper classes which abstract the configuration mechanisms (web.config app settings keys vs cscfg configurationsettings) in order to be able to use the different configuration mechanisms (e.g. check cscfg and fall back to web.config or the other way round or something along that lines).
Update: If you are using a "recent" azure SDK (1.7+) here is CloudConfigurationManager which might do most of the work for you.

Is it possible to update configuration settings programmatically?

We are experimenting with deploying an MVC app as an Azure web role. Currently the app is being hosted locally on our server. It has a few appSettings in Web.Config that can be changed by the users as part of the "Administration" module of the application.
I know this isn't a good practice for Azure because there will potentially be multiple instances of the application running with multiple Web.Configs, which makes updating them all a nightmare (if not impossible). My understanding is that the ConfigurationSettings specified in the service definition should be used instead of Web.Config so that settings are defined globally in one place that all the instances of the application can access.
My question is is it possible to programmatically update ConfigurationSettings similar to the way we update Web.Config settings, or would it be better for us to move those settings into a database or something else?
Yes, but unfortunately it is definitely not simple to do.
Follow this URL: http://msdn.microsoft.com/en-us/library/windowsazure/ee460809.aspx
It talks about a Svc Management API call that you can make to read/write the Service Configuration. It is a 64-base string which you'll need to decode, find XML flags in it that you want to change and re-encode it back and send it back to the API.
Not pleasant, but doable.

Changing/retrieving configuration settings on role start (Azure)

I'm trying to make a service to more easily configure configuration values on Azure applications. Right now, if I want to change a setting that it the same over 7 different environments, I have to change it in 7 different .cscfg files.
My thought is I can create a webservice, that the application will query for its configuration values. The webservice will look in a storage place, like Azure Tables, and return the correct configuration values.
I've been able to integrate this into a deployment script pretty easily (package the app, get the settings, change the cscfg file, deploy). The problem with that is every time you want to change a setting, you have to redeploy.
Finally the question - Is there a way I can retrieve the configuration settings after the application starts, on role start? It would of course need a base set of settings for the app to start. Retrieving the settings from the web service on application start would be good. Any way that I don't have to redeploy the application and that it will retrieve them automatically will work.
Thanks in advance!
Just use the .cscfg for the minimum set (common to all environment) of configurable settings. The use your web services for rest of the configurations. And don't modify your .cscfg. Just have a settings provider that retrieves settings from web service (via polling or message signalling - pub/sub model). And have a reinitialize settings procedure in place for this settings provider and all the services/components that rely on configurable settings.

Resources