Accessing Azure Key Vault values from Azure App Configuration. Solving the 403 Forbidden
So recently I had to develop an Azure function app. I wanted centralised configuration that would/could be shared across multiple apps so I added Azure App Configuration.
I knew any secrets needed to be held in Azure Key Vault. App Configuration has an option to add a key vault reference so I figured it would automatically work it out… Well how wrong was I when I started getting 403. It took me a while to work out what was going on and how to resolve the issue as Microsoft have nothing that is worth while in terms of documentation regarding this.
I have added the code to create everything and broken it down into 3 parts.
Part1: Create the app config with a key value pair and get the value back into C#
Part2: Create Key Vault and add a secret to it and a reference to App Configuration. Update the code to add a Key Vault configuration…and watch the tests fail with a 403 Forbidden
Part3: Add the extra code to allow App Configuration to get the Key Vault secrets.
All code can be found at: https://github.com/byronbayer/CodeSamples/tree/main/AppConfigAndKeyVault
I open the solution in Visual Studio and also open the folder in VS Code. This allows me to run the tests in Visual Studio and run the powershell scripts in VS Code
Part 1
First run the Create Infrastructure.ps1 script in the Part1 folder. This will create the App Configuration and Key Vault and add a non secret value to the App Configuration. It will also give you the connection string to the App Configuration which you will need to copy onto the C# Tests application.
Open the solution in Visual Studio which is found in the CodeSamples\AppConfigAndKeyVault\Code\AppConfigAndKeyvault folder. Paste the connection string that you got from running the previous script into the Constance.cs file for the ConnectionString value
Open the Part1.cs file and run the test. At this stage it should pass as we are only going off to app configuration. If you are getting a 403 at this point check the connection string is correct in Constance.cs.
So what is the code doing?
It is creating a configuration builder then adding an AzureAppConfiguration to the configuration. The options in here are selecting any App Configuration and then connecting with the App Configuration connection string.
We then build the Configuration and test that the value we have in the key value “platform:NonSecretValue” is “This is not a secret”. This works perfectly.
Part 2
So now we want to add a secret into key vault and then add a reference to that key vault value into App Configuration.
Run the UpdateKeyvaultValues.ps1 powershell script in the Part2 folder.
This adds a secret into Key Vault and then adds the reference to that secret into App Configuration
I have added the bulk of the test code into the constructor here as it will run for each test.
I added a new line to configure Key Vault using a Default Azure Credentials
If you run the tests in part 2 now you will see you are getting
“code”:”Forbidden”,”message”:”Access denied to first party service….”,”innererror”:{“code”:”AccessDenied”}}}.
(Tests in Part1 will now also fail with “No key vault credential or secret resolver callback configured, and no matching secret client could be found..” as there is no key vault resolver set up.)
Lets move on to Part3 where we look at the solution
Part 3
First run the GetTenant.ps1 script in the Part3 folder and copy the tenantId to the DefaultTenantId property in Constance.cs file.
Now if you run the tests in Part3 they should both pass for non secret values and secret values. Lets see what had to be done.
I had to configure the key vault options.
If the value in App Configuration is stored in Key Vault then the configured key vault will kick off. Here I m getting the secret name and version from the string that is stored in App Config. I then call a method called GetAzureCredentials() which is the bit that makes all this work.
The main part about the method GetAzureCredentials() is that the DefaultAzureCredentialOption.VisualStudioTenantId is set to the tenant id that we got out of powershell earlier. Once this is set, you can retrieve non secret and secret (stored in key vault) App configuration values.