Improving security of your apps' source-code in a few minutes
Tags: azure, security, dotnet
Published: 2021-06-12 10:06:30

## Introduction 📄
It's a common mistake that every developer tends to make, especially early on: adding secrets to source-control or saving them somewhere else in plain-text. A good example of this is an API key stored in the web.config or settings.json.

Saving secrets as plain-text is a bad-practice can be a security risk. But where should you save your secrets? And how much does it cost to implement an alternative solution?

## Enter: Azure Key Vault 🔑
[Azure Key Vault](https://azure.microsoft.com/en-us/services/key-vault/) (AKV) is a service provided by Microsoft Azure that lets you store encryption keys, secrets and certificates. AKV can be easily integrated with almost any other service in Azure, but it doesn't stop there. It can easily be integrated in other environments too: local machines, apps, if you want to go crazy you can even use it in an AWS environment.

*Make sure to check the pricing of AKV. It's pretty cheap and you can make it cost virtually nothing if you're using caching and minimizing the operations to AKV.*

## How does it work?
*I'll primarily focus on storing secrets in this post, but you can also store [keys](https://docs.microsoft.com/en-us/azure/key-vault/keys/about-keys) and [certificates](https://docs.microsoft.com/en-us/azure/key-vault/certificates/about-certificates) in AKV.*

### Storing and retrieving 📂
The easiest way to store and retrieve secrets is using the Azure Portal. You give your secret a name, a value and store it. You can retrieve the value of the secret on the same screen. For more complex scenario's, like integrating within your application you can use the REST API or any of the available client-libraries.

### Encryption 🔐
When storing secrets, AKV encrypts them and decrypts them when you want to retrieve them. AKV never knows what secret you've stored. 

### Security 👨‍✈️
The basic security principle is that you need to authenticated **and** have the correct authorization level in order to interact with AKV. By default AKV is only accessible by the creator of the AKV. By using access-policies you can give access to other principals.

You can make the AKV even more secure by, for example, adding IP-restrictions or isolating the AKV in a virtual network.

---

## Setup authentication with AKV 🔧
There are two ways you can authenticate to AKV with your application or service. In both cases, you first need to setup an [Azure Active Directory](https://azure.microsoft.com/en-us/services/active-directory) (free tier is sufficient!). I'll explain the basic configuration proces, but a more extended tutorial can be found in my [GitHub repository](https://github.com/SietseT/dotnet-keyvault-examples), which also includes an example website you can run or deploy.

### In Azure
If your application or service is hosted in Azure you're in luck: integration is super-easy. The [recommended](https://docs.microsoft.com/en-us/azure/key-vault/general/authentication) authentication method is by using a [managed identity](https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet) for your service. 

### Other environments
When hosting your application/service outside Azure, you need to setup an [App registration](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) in Azure Active Directory. You'll also need to create a [client-secret](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app#add-credentials).

### Grant access
When you've setup app registration or managed-identity, head over to the *Access policies* tab in your AKV and grant the correct permissions (get secrets) to the app registration or managed-identity.

---

## Access secret in code ✏️
Retrieving a secret in code is very easy. This example is based on a .NET application. Using the client-library for .NET we can retrieve a secret with this code:

```
var client = new SecretClient("<keyvaulturi>", new DefaultAzureCredential());
var secret = await client.GetSecretAsync("mysupersecretsecret");
```

You can find the URI of your AKV in the Azure Portal. For this to work outside Azure, you will need to set some environment variables:
- AZURE_CLIENT_ID (Client ID from app registration)
- AZURE_TENANT_ID (Tenant ID from app registration)
- AZURE_CLIENT_SECRET (Secret you created in the app registration)

That's it! 🥳

---

## Conclusion 💡
After integrating AKV with your application or service you may have noticed credentials or hints of how your application authenticates with AKV are **not** stored in your code. The only thing that's saved in the code is the URL of the AKV, but even that can be hidden and saved in an environment variable to make things even more secure. 

Another advantage is that all your secrets are stored in one location, instead of possibly multiple locations. This makes management easy.

Speaking of management, by looking at the access-policies of the AKV you can easily identify what and who has access.

---

## Key (hah.) take-aways 🔑
✔️ Azure Key Vault (AKV) allows you to safely store secrets, keys and certificates

✔️ Integrating AKV with your application or service is super easy 

✔️ Costs virtually nothing, but takes the security of your application or service to the next level

## Resources
- [Example on GitHub](https://github.com/SietseT/dotnet-keyvault-examples)
- [Azure Key Vault documentation](https://docs.microsoft.com/en-us/azure/key-vault/general/)