Azure-Samples / app-service-msi-keyvault-dotnet

Sample that shows how to fetch a secret from Azure Key Vault at run-time from an App Service with a Managed Service Identity (MSI).
MIT License
64 stars 67 forks source link

page_type: sample languages:

Use Key Vault from App Service with Azure Managed Identity

Background

For Service-to-Azure-Service authentication, the approach so far involved creating an Azure AD application and associated credential, and using that credential to get a token. The KeyVault use from Web Application shows how this approach is used to authenticate to Azure Key Vault from a Web App. While this approach works well, there are two shortcomings:

  1. The Azure AD application credentials are typically hard coded in source code. Developers tend to push the code to source repositories as-is, which leads to credentials in source.
  2. The Azure AD application credentials expire, need to be renewed; otherwise, it will lead to application downtime.

With Azure Managed Identity, both problems are solved. This sample shows how a Web App can authenticate to Azure Key Vault without the need to explicitly create an Azure AD application or manage its credentials.

Here's another Auto deploy or operate Azure resources on Windows sample that shows how to programmatically deploy an ARM template from a .NET Console application running on an Azure VM with a Managed Identity.

Here's another How a .NET Core application deployed on an Azure Linux VM sample that shows how to programmatically call Azure Services from an Azure Linux VM with a Managed Identity.

Prerequisites

To complete this tutorial:

If you don't have an Azure subscription, create a free account before you begin.

Create an App Service with an Azure Managed Identity

Use the "Deploy to Azure" button to deploy an ARM template to create the following resources:

  1. App Service with Azure Managed Identity.
  2. Key Vault with a secret, and an access policy that grants the App Service access to Get Secrets.

    Note: When filling out the template you will see a textbox labelled 'Key Vault Secret'. Enter a secret value there. A secret with the name 'secret' and value from what you entered will be created in the Key Vault.

Review the resources created using the Azure portal. You should see an App Service and a Key Vault. View the access policies of the Key Vault to see that the App Service has access to it.

Grant yourself data plane access to the Key Vault

Step 1: Set access policy.

Step 2: Copy and save Key Vault Url.

Select Overview > DNS Name, copy the associated Key Vault Url to the clipboard, then paste it into a text editor for later use.

Run the application

Clone the repo to your development machine.

git clone https://github.com/Azure-Samples/app-service-msi-keyvault-dotnet.git

Run the application on your local development machine

To run the sample, this solution requires a Key Vault URL to be stored in an environment variable on the machine , and Register an application with the Microsoft identity platform, then grant the access policy by Step 1: Set access policy.

Linux

export KEY_VAULT_URI="<YourKeyVaultUrl>"

Windows

setx KEY_VAULT_URI "<YourKeyVaultUrl>"

Deploy the Web App to Azure

Use any of the methods outlined on Deploy your app to Azure App Service to publish the Web App to Azure.

Step 1: Set environment variable in app service.

After you deploy it, browse to the web app. You should see the secret on the web page.

How to use AzureCliCredential

There are 2 approaches to use AzureCliCredential. First way is create AzureCliCredential directly, the other way is use AzureCliCredential which is chained in DefaultAzureCredential.

  1. Create AzureCliCredential directly.
    
    using Azure.Identity;

var credential = new AzureCliCredential();

2. Use `AzureCliCredential` which is chained in `DefaultAzureCredential`.
```C#
using Azure.Identity;

var defaultAzureCredentialOptions = new DefaultAzureCredentialOptions();
defaultAzureCredentialOptions.ExcludeAzureCliCredential = false;
defaultAzureCredentialOptions.ExcludeEnvironmentCredential = true;
defaultAzureCredentialOptions.ExcludeInteractiveBrowserCredential = true;
defaultAzureCredentialOptions.ExcludeManagedIdentityCredential = true;
defaultAzureCredentialOptions.ExcludeSharedTokenCacheCredential = true;
defaultAzureCredentialOptions.ExcludeVisualStudioCodeCredential = true;
defaultAzureCredentialOptions.ExcludeVisualStudioCredential = true;

// Actually only include AzureCliCredential in DefaultAzureCredential.
var credential = new DefaultAzureCredential(defaultAzureCredentialOptions);

Summary

The web app was successfully able to get a secret at runtime from Azure Key Vault using your developer account during development, and using Azure Managed Identities when deployed to Azure, without any code change between local development environment and Azure. As a result, you did not have to explicitly handle a service principal credential to authenticate to Azure AD to get a token to call Key Vault. You do not have to worry about renewing the service principal credential either, since Azure Managed Identities takes care of that.

Troubleshooting

Please see the [troubleshooting section] of the AppAuthentication library documentation for troubleshooting of common issues.

[troubleshooting section]:https://docs.microsoft.com/en-us/azure/key-vault/service-to-service-authentication#appauthentication-troubleshooting