Useful tools to manage your application's secrets
Posted Jul 19, 2019 | 7 min. (1464 words)When you build and deploy an application, chances are that you need to store some form of secrets. These are typically things like credentials for 3rd party systems and database credentials.
As an ASP.NET Core developer, Microsoft provides you with an easy way to store secrets like these in your development environment, namely the Secret Manager. The Secret Manager allows to store secrets inside a JSON file on your local computer, ensuring this sensitive information is never accidentally checked into source control.
But how do you handle the safe storage of secrets in a production environment? These secrets are typically the sort of information that you would not want anyone except for a few key personnel—and of course your application—to be able to access.
In this blog post, we’ll have a look at how you can safely store and retrieve secrets when hosting your ASP.NET Core application on Azure or Amazon Web Services, as well as some generic solutions you can use independent of the hosting platform.
Why not store it in source control?
Before we start, let’s briefly talk about why we shouldn’t store secrets in source control. After all, ASP.NET Core has a very convenient way of specifying configuration settings based on the environment, allowing you to specify all the configuration values for your production environment inside your appSettings.Production.json
file.
For certain types of configuration this is a completely valid solution, but adding sensitive information to this file means that it will be checked into source control, allowing anyone who has access to the source effectively access to things like your production database or 3rd party systems. We all would like to think that you can trust all the developers on your team, but that is not always the case. Add to that the fact that the computers of the developers themselves may be compromised, allowing bad actors to gain access to sensitive information.
The bottom line is that each extra person who has access to this information increases the risk footprint that you need to protect against.
Then we also need to remember that information stored inside GitHub, even if it is inside a private repository, cannot be assumed as being safe from prying eyes. One of the most famous cases like this that I remember was the one involving social media scheduling company Buffer back in 2013.
In their case, the security breach was 2-fold. Firstly, the hackers were able to extract access tokens from their hosted MongoDB database due to a password being stolen from an employee. That in itself was not enough to enable hackers to gain access to the user’s accounts. In the case of Buffer, the hackers were also able to obtain two other crucial pieces of information called a Twitter OAuth Consumer Key and Consumer Secret.
With this information, along with the stolen access tokens obtained from the MongoDB database, the hackers were able to wreak havoc and post spam to the Buffer users’ social media accounts. This would not have been possible if the hackers did not have access to that OAuth consumer key
and consumer secret
.
There are also many other similar cases where hackers were able to obtain access to secret information stored in GitHub to steal user information and even run up huge bills on hosting providers such as Amazon.
So, now that we understand why it is a bad idea, let’s look at some ways you can safely store secrets used by your production ASP.NET Core applications.
Azure App Service
If you are hosting your application on Azure App Service, there are a couple of ways that you can use to store application secrets, namely storing it in your application settings, or using Azure Key Vault.
Storing it in your application settings
Azure App Service allows you to store configuration settings for your App Service. By specifying these secrets inside the Azure Portal, you can ensure that only certain people have access to these settings.
The settings you specify on your App Service are available at runtime as environment variables in your application, so all you need to do is to ensure that you are using the Environment Variables Configuration Provider.
To configure application settings for your App Service, go to the Configuration section of your App Service and then select Application settings. From here you can add your environment variables as key-value pairs.
Quick tip: You can quickly edit multiple environment variables by selecting Advanced edit. This will open a JSON editor, allowing you to quickly edit multiple variables at once:
Using Azure Key Vault
Storing secrets in your App Service application settings is a step up from storing it in a JSON configuration file, but Azure actually provides an even more secure way to handle these settings. Azure Key Vault allows you to encrypt any application secrets using Hardware Security Modules (HSMs).
It also allows you much more granular control regarding which people and resources have access to secrets. It can log access to keys, allowing security administrators better visibility of which resources access these secrets.
For more information on using Azure Key Vault in your ASP.NET Core application, please refer to the Microsoft documentation on the Azure Key Vault Configuration Provider in ASP.NET Core
Amazon Web Services
AWS Secrets Manager
If you are hosting your application on Amazon Web Service, you can make use of AWS Secrets Manager to securely store and access secrets.
Access to secrets can be managed through IAM Policies or resource-based policies
Integration with ASP.NET Core can be done by making use of the Kralizek.Extensions.Configuration.AWSSecretsManager NuGet package, which integrates seamlessly with the standard ASP.NET Core configuration extensions. Alternatively, you can retrieve secrets manually using the AWS SDK for .NET.
For a detailed guide on how to configure and use AWS Secrets Manager in your ASP.NET Core application, please refer to the following 2-part series by Andrew Lock:
- Secure secrets storage for ASP.NET Core with AWS Secrets Manager (Part 1)
- Secure secrets storage for ASP.NET Core with AWS Secrets Manager (Part 2)
AWS Systems Manager Parameter Store
The AWS Systems Manager Parameter Store allows you to store plain-text or encrypted data in a hierarchical data store. As with AWS Secrets Manager, you can also control access to parameters using AWS Identity and Access Management (IAM)
For ASP.NET Core developers, Amazon provides the Amazon.Extensions.Configuration.SystemsManager NuGet package which integrates with the standard ASP.NET Core configuration extensions.
For more guidance on integrating AWS Systems Manager Parameter Store with your ASP.NET Core application, you can refer to the following documents:
Other alternatives
Before closing off the blog post, lets briefly touch on your options when using other environments.
Docker
For environments making use of Docker, you can make use of Docker Secrets which allows you to manage and securely transmit secrets required by your applications and services.
In terms of integrating with ASP.NET Core, you can refer to the following blog posts for guidance and sample:
Google KMS
If you are running in Google Cloud, you can use Cloud Key Management Service (KMS). It the case of KMS, secrets are encrypted and stored in source control (or elsewhere) and then at runtime these secrets are decrypted to be used in your application.
For making use of KMS in ASP.NET Core, you can refer to the following:
- Keeping Secrets in ASP.NET’s appsettings.json
- .NET Cloud Key Management Service (KMS) ASP.NET Sample
Other available options for managing application secrets
We will conclude the list of options with the above-mentioned products, but there are many more options available to you to store and manage secrets in production applications, such as Vault by Hashicorp, EnvKey and others.
How we handle sensitive information at Raygun
At Raygun, we take the security of your customer’s information seriously. We give you have complete control over the data that is transmitted to Raygun to remove any sensitive data prior to transmission. We provide options for handling this in our developer libraries.
Secondly, we give you have complete control over the data that is transmitted to Raygun to remove any sensitive data prior to transmission. We provide options for handling this in our developer libraries.
For more information regarding this, please refer to the Raygun Security page, as well as our blog post on how Raygun’s security measures keep your customer’s data safe
Conclusion
In this blog post, we discussed the reasons for keeping your secrets out of source control, and the looked at the options available to you to manage and consume secrets in an ASP.NET Core application.
This article was written by Jerrie Pelser, freelance developer and curator of ASP.NET Weekly, which is a weekly digest of all the best ASP.NET related news and blog posts.