Azure key vault is a service to store and manage keys, secrects and certificates that you can use for your applications. In this blog post I want to quickly show how to create a key vault and how to use it.
Key vault is a secure key management service that allows to manage keys, application secrets and certificates. The keys are stored in hardware security modules (FIPS 140-2 Level 2) and even Microsoft does not see them. Pretty cool stuff, so why should someone use Azure Key Vault?
A common problem is how to manage keys and secrets for your applications? Where to store them? And how to ensure that they have a defined lifetime? Azure key vault allows to achieve all these things. A few features are:
- Save keys in Azure in a safe place
- Keep encryption keys in hardware security modules (FIPS140-2 Level 2+)
- Control keys from a single place
- Control lifetime and renewal of keys
- Let other AD users/groups manage access to secrets
- Access keys from your applications
- Automatically rotate keys
It especially helps you to solve the issue of storing keys/secrets for your applications. If you develop an application – where do you put e.g. storage keys or other secrets? Sometimes developers hardcode them into the code. Other developers store them in the configuration (e.g. app.config) and just a few use something like azure key vault.
Ok, but what is a key vault? A key vault is a container for keys and secrets that are managed together. If you develop an application, then it makes sense to create one key vault per application because the access control and also the billing is per key vault. If you have all keys/secrets stored in one key vault, then each user that has access to that key vault can read all keys/secrets that in the key vault. So you should definitely create one key vault per application. As a key vault itself is for free, this shouldn’t be a problem and helps you to secure your stuff. The pricing for key vault is pay per usage of keys (see: Key Vault Pricing Details).
The key vault allows you store:
- Key: A cryptographic key (RSA 2048) that you can use to decrypt/sign with the key
- Secret: A secret is a sequence of bytes unter 25KB – for example a connection string, PFX file, AES encryption key.
So, enough introduction, let’s start to create key vault and use it:
Create a key vault
…by searching for “key vault” and add:
Create a secret
Let’s directly create a new secret. This can be a password, a connection string (SQL, Storage Account, …), a certificate or whatever you need. You can do this via Azure portal:
or you can do it via powershell:
Get-AzureRmKeyVault # shows all available key vaults # create a new secret $testkey = ConvertTo-SecureString -String "MyTestKey" -AsPlainText -Force Set-AzureKeyVaultSecret -VaultName codehollow-keyvault -Name "TestKey" -SecretValue $testkey
Read a secret
if the secret was successfully created, you can already read it via powershell:
# get value of existing secret $secret = Get-AzureKeyVaultSecret -VaultName codehollow-keyvault -name "TestKey" $secret .SecretValueText
Read a secret from a c# application
Reading a secret from a c# application requires a bit more steps, because we will not authenticate as our user but as application. Therefore we need to create an application in Azure AD and add few packages and stuff to our application:
1. step: Add Azure application
Open Azure Active Directory in the portal – “App registrations” – “New application registration”:
give it a name and a (non-relevant) sign-on url – e.g.:
Name: keyvaultapp
Sign-on URL: http://localhost/mykeyvaultapp
Save it – open the application and copy the application id (=clientId). Create a new key and copy the value of the key (=clientSecret)
2. step: Permissions for the new application
Jump back to the key vault – open the principals and add a new principal (the application we created in the previous step):
Leave the template empty, select the application from the previous step as principal and set “Secret permissions” to “Get”:
3. step: Use it in your C# application
Create a new application and add the NuGet packages “Microsoft.Azure.KeyVault” and “Microsoft.IdentityModel.Clients.ActiveDirectory”:
Now you can access the secret via the following code:
using Microsoft.Azure.KeyVault; using Microsoft.IdentityModel.Clients.ActiveDirectory; using System; using System.Threading.Tasks; namespace ConsoleAppDotnetCore { class Program { const string CLIENTID = "[ENTER CLIENT ID]"; // move this to app.config const string CLIENTSECRET = "[ENTER CLIENT SECRET]"; // move this to app.config const string SECRETURI = "https://yourname.vault.azure.net/secrets/SecretKey"; // move this to app.config static void Main(string[] args) { KeyVaultClient kvc = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(GetToken)); var secret = kvc.GetSecretAsync(SECRETURI); Console.WriteLine(secret.Result.Value); } // thanks to_ https://docs.microsoft.com/en-us/azure/key-vault/key-vault-use-from-web-application public static async Task<string> GetToken(string authority, string resource, string scope) { var authContext = new AuthenticationContext(authority); ClientCredential clientCred = new ClientCredential(CLIENTID, CLIENTSECRET); AuthenticationResult result = await authContext.AcquireTokenAsync(resource, clientCred); if (result == null) throw new InvalidOperationException("Failed to obtain the JWT token"); return result.AccessToken; } } }
CLIENTID, CLIENTSECRET and SECRETURI should be stored in the application config file. The values for clientid and clientsecret can be found at the Azure Active Directory app registration (see step 1). The secret uri is the uri that you can find at the key vault when you open the secret (Key vault – Secrets – your secret – current version):
So far so good – we can already read a secret from a c# application and also from powershell. This is already useful for many use cases, but there are still a few things to discover. How to authenticate an application with a certificate? How to use key vault from an azure function? How to use keys to encrypt/decrypt?
I will write a few more blog posts about azure key vault – so stay tuned!
Additional information
Get started with Azure Key Vault: https://docs.microsoft.com/en-us/azure/key-vault/key-vault-get-started
Use Azure Key Vault from a Web Application: https://docs.microsoft.com/en-us/azure/key-vault/key-vault-use-from-web-application
Azure Key Vault libraries for .NET: https://docs.microsoft.com/en-us/dotnet/api/overview/azure/key-vault
9 Responses
[…] Get started with Azure key vault by Armin Reiter […]
[…] https://codehollow.com/2017/11/get-started-azure-key-vault/ […]
this was really useful to me as a new c# starter! thank you for writing up in such a clear way including the nuget references and so on.
excellent tutorial!
hello. Sorry but I can’t find CLIENTSECRET. Could you write exactly how in’s call and where from in Azure?
Hello, please check step 1 in the section “Read a secret from a c# application”:
Go to Azure Active Directory – App registrations – “your app” – Settings – Keys – enter a name and press “save” -> you should now see your secret
Thanks Armin for such good explanation! Only have a question that’s confusing me. You say CLIENTID, CLIENTSECRET and SECRETURI should be moved to app.config. My winforms application is distributed to customers. If they use IL-SPY they’ll be able to see the contents of these 3 consts. Will they be able to find out the secret (Azure SQL Server connectionstring password in my case) if they know these 3 consts? If so, what would you suggest to avoid this assuming I’m stuck with winforms for now.
Thanks again!
Sergio
if possible, I would not directly connect the winforms application to the sql server. It’s better to have an api in between. If you have no other option than connecting directly to azure sql, then you could use azure active directory to authenticate the client user and use the received token to connect to the sql server or to get the secret from key vault. With the key vault option, you could also configure auto rotation – see: https://docs.microsoft.com/en-us/azure/key-vault/key-vault-key-rotation-log-monitoring
hth and best regards,
Armin
Hi there to all, the contents present at this website are
actually remarkable for people experience, well, keep up the good work fellows.
Good day,
I am getting this error on my return on the var secret = kvc.GetSecretAsync(SECRETURI);
secret
Id = 47, Status = WaitingForActivation, Method = “{null}”, Result = “{Not yet computed}”
AsyncState: null
CancellationPending: false
CreationOptions: None
Exception: null
Id: 47
Result: null
Status: WaitingForActivation
Not sure whats wrong. Can you please help me out?