Since the earliest attempts at application development, programmers have needed to include credentials as part of their application. Connecting an application to a database, artifact repository, or third-party APIs require a username and password pair or a secure token. In addition, it’s always been a challenge to provide these secrets to the application in a secure manner.
The challenge of protecting secrets has only increased with time, as has the complexity of the systems which use these secrets. In this article, we’re going to discuss .NET Core and how to securely set up, store, and use secrets in your application.
.NET Core and Secrets
Building on the success of Microsoft .NET, .NET Core is an open-source framework that allows users to expand beyond the Microsoft Ecosystem and execute their code across multiple platforms and architectures. The 2019 StackOverflow Developer Survey found that .NET Core was the Most Loved Non-Web Framework. It seems apparent that .NET Core adoption is likely to increase in the future, and as such, it’s essential to understand how to integrate a secure secret strategy with your .NET Core applications.
There are several popular methods used to store and use secrets in .NET applications. These are:
- Environment Variables
- User Secrets in .NET Core
- Leveraging secret variables as part of a Continuous Integration (CI) Pipeline
- Using a Secret Vault or Key Management Service
Let’s consider each of these approaches in turn, and discuss some of the pros and cons associated with using them in your application.
Environment Variables
When you use environment variables to store secrets, you set values at the user level in a specific environment. Once you’ve set the value, you can reference it by name – from the code or command line – without needing to know the value itself.
An overwhelming advantage of this approach is that you can create different environment variables depending on where you deploy your application. As such, you can easily configure different secrets to be used locally, in a test environment or out in production. The downside is that any application running on the same machine can also access these same variables. Environment variables are also not encrypted, which raises additional concerns about security.
CI Secret Variables
Tangentially related to environment variables are variables, and focused on application deployment are secret variables included with your build pipeline. Most teams that I know of use Jenkins, but the same features exist in Travis, AWS CodeDeploy, and Azure Pipelines. These systems encrypt the secret values when entered, and protect them from inadvertent exposure in log files and console outputs.
You can use secret variables in your build pipeline to add API Keys, database passwords, and other sensitive credentials to the deployed machine. These secrets can be injected into the application at startup or added as environment variables (see above). Their usage is limited to the scope of building and deploying an application. Secret management is also not a core-competency of CI tools.
User Secrets in .NET Core
One of the problems with including secrets in an external configuration file is that these often get checked into version control systems and thus get exposed to a broader audience. To support the concept of an external “secrets” file, .NET Core includes User Secrets modules. Visual Studio creates and manages the User Secrets as a JSON file, within the AppData structure of the local machine.
The User Secrets file remains with the machine where you created it, which requires you to add the secrets to each application during deployment. When deploying the application, you’ll need to add each of the secret values as settings to the application. You can add these values automatically as part of the CI process.
Secrets Management Systems
When we discussed using secret variables on a CI pipeline, I mentioned that secrets management is not a core competency of these tools. Secrets management is vital to the integrity of your organization and its applications that you should be willing to invest in ensuring that you have a tried and true management system in place.
In addition to providing you with a secure repository for your most sensitive data, a comprehensive secrets management system should also:
- Allow real-time updating of credentials as needed.
- Support policies for password rotation.
- Support role-based access control (RBAC).
- Centralize secrets management for all your applications.
If you’re making your first foray into the secrets management space, Conjur from CyberArk is an excellent place to start. Based on years of world-class support, Conjur is an open-source solution, built with the future of the web in mind. Various open source tools, such as Summon and Secretless Broker, are under constant development and can help you securely deliver secrets to your applications.
Learning More
If you would like to learn more about Conjur and other open-source content, you can join the conversation on the CyberArk Commons Community. Conjur and other open-source projects are a part of the CyberArk Commons Community, an open community dedicated to developers, engineers, cybersecurity researchers, and other technically-minded people. To discuss this and other topics, such as Kubernetes, Secretless Broker, Conjur, CyberArk Threat Research, join me on the CyberArk Commons discussion forum.
Mike Mackrory is a Global citizen who has settled down in the Pacific Northwest — for now. By day he works as a Lead Engineer on a DevOps team, and by night, he writes and tinkers with other technology projects. When he’s not tapping on the keys, he can be found hiking, fishing and exploring both the urban and rural landscape with his kids. Always happy to help out another developer, he has a definite preference for helping those who bring gifts of gourmet donuts, craft beer and/or single-malt Scotch.