Keeping Sensitive Configuration Data Out of Source Control
Most applications today deals with some form of sensitive information. The most commonly seen are database connection strings, API keys, token etc. The web.config seems the best place to have these values, but it definitely is not. In most cases it gets pushed into the source control systems as well. If it is a private repository then you at least have one level of security on top of it. It still exposes sensitive information to anyone who has access to the repository. It’s worse when the repository is public.
There are different ways you can avoid pushing sensitive data into source control. In this post, I will explore options that I am familiar with.
Use configuration files as template definitions for the configuration data your application requires. Have the actual values stored elsewhere
If you are deploying your application as a Web App on Azure, you can store application settings and connection strings in Azure. At runtime, Windows Azure Web Sites automatically retrieves these values for you and makes them available to code running in your website. This removes the need for having sensitive data in the configuration file.
Release management tools like Octopus Deploy, Microsoft Release Management, that performs configuration transformation. It supports creating different environments (development, production) and corresponding configurations. On creating a package for an environment, it applies the corresponding environment configurations
Packaging embeds the configuration value into the configuration file. This makes it available to anyone who has access to the host systems.
Azure Key Vault acts as a centralized repository for all sensitive information. Key vault stores cryptographic keys and Secrets and makes them available over a HTTP Api. The objects (keys and secrets) in key vault has unique identifier to retrieve them. Check Azure Key Vault in real world application for more details on how to achieve this. A client application can authenticate with Azure Key Vault using a ClientID/secret or ClientID/certificate. Using certificate to authenticate is the preferred approach. To get Keys/Secret from key vault all you need is the AD Application Id, the client secret or certificate identifier and the key/secret names. The certificate itself can be deployed separately into the application host.
<appSettings> <add key="KeyVaultUrl" value="https://testvaultrahul.vault.azure.net"/> <add key="ADApplicationId" value="" /> <add key="ADCertificateThumbprint" value="" /> <add key="DbConnectionString" value="SqlConnectionString"/> <add key ="ApiToken" value="ApiToken/cfedea84815e4ca8bc19cf8eb943ee13"/> </appSettings>
Key Vault supports Managed Service Identity which makes authenticating with it even more easier if your application is deployed in Azure. You no longer have to add any configuration related to key vault to the applications config file.
If you are using the ‘client secret’ to authenticate then the configuration file will have the Secret. In either cases, you should follow either of the previous approaches to keep the Application Id and authentication information out of configuration. The advantage of using Key Vault is that it is a centralized repository for all your sensitive data, across different applications. You can also restrict access permissions per application.
These are some approaches to keep sensitive information out of source control. What approach do you use? Irrespective of the approach you use, make sure that you don’t check them in!