Azure, Azure, and more Azure - Key Vault | Basic Workflow and Links

Key Vault

Notes

Your application requires service passwords, connection strings, and other secret configuration values to do its job. Storing and handling secret values is risky, and every usage introduces the possibility of leakage. Azure Key Vault, in combination with managed identities for Azure resources, enables your Azure web app to access secret configuration values easily and securely without needing to store any secrets in your source control or configuration.

Azure Key Vault managed identities
Source

Workflow

The idea of the exercise is to store the DB connection as a secret in a Key Vault Instance and reference it in the app using a unique secret URI. We will need to create a Key Vault with the database connection string stored as a secret and reference it as App service settings using key vault reference syntax.

For our example, I’m going to use the following repo https://github.com/dotnet-architecture/eShopOnWeb and deploy the PublicApi using Azure Web App. But first, let’s create the Azure Key Vault.

You can create a key vault using the Azure CLI:

az keyvault create \
    --resource-group [sandbox resource group name] \
    --location eastus \
    --name <your-unique-keyvault-name>

Then, add a secret to the key vault:


az keyvault secret set \
    --name eshop-database \
    --value "Server=tcp:YOURDATABASEURL.database.windows.net,1433;Initial Catalog=eshop-Catalog;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;Authentication='Active Directory Default';" \
    --vault-name <your-unique-keyvault-name>

Let’s do a code change. Open your WebAPI project and add the following NuGet packages:


dotnet add package Azure.Identity
dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
dotnet restore

Then, open the Program.cs file and add the following code:


var vaultName = builder.Configuration["KeyVault:BaseUrl"];
builder.Configuration.AddAzureKeyVault(
    vaultUri: new Uri(uriString: vaultName),
       credential: new DefaultAzureCredential());

public static void ConfigureServices(IConfiguration configuration, IServiceCollection services)
{

    var catalogConnectionString = configuration["eshop-database-catalog"];
    var identityConnectionString = configuration["eshop-database-identity"];

    // Add Category DbContext
    services.AddDbContext<CatalogContext>(c =>
        c.UseSqlServer(catalogConnectionString));

    // Add Identity DbContext
    services.AddDbContext<AppIdentityDbContext>(options =>
        options.UseSqlServer(identityConnectionString));
}

Now, we need to add the Key Vault URL to the app settings. Open the appsettings.json file and add the following code:

{
  "KeyVault": {
    "BaseUrl": "https://<your-unique-keyvault-name>.vault.azure.net/"
  }
}

Let’s test locally

With this configuration done, we are good to deploy that webapp to Azure. The only configuration setting you need to add is the Key Vault URL. You can add it using the Azure CLI:

az webapp config appsettings set \
    --resource-group [sandbox resource group name] \
    --name <your-unique-app-name> \
    --settings KeyVault:BaseUrl=https://<your-unique-keyvault-name>.vault.azure.net/

After testing the app, you will see nothing works. So, you need to enable the managed identity. It can be easily done using the Azure CLI:


az webapp identity assign \
    --resource-group [sandbox resource group name] \
    --name <your-unique-app-name>

After creating it, get the principalId and with it, grant access to our keyvault:

az keyvault set-policy \
    --name <your-unique-keyvault-name> \
    --object-id <your-app-principal-id> \
    --secret-permissions get list

Now, you can test the app again and it should work.