3
votes

Is it possible to give access to a key vault to a user assigned identity?

In Managed Identities from the azure portal I created a new Identity "KeyVaultIdentity", which I assigned it to a web application (in Identity, user assigned identities tab). In access policies from key vault I added the new created "KeyVaultIdentity" identity and offered permissions to access the secrets.

I am using the following code to access the key vault:

try
        {
            /* The below 4 lines of code shows you how to use AppAuthentication library to fetch secrets from your Key Vault*/
            AzureServiceTokenProvider azureServiceTokenProvider = new AzureServiceTokenProvider();
            KeyVaultClient keyVaultClient = new KeyVaultClient(new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));
            var secret = await keyVaultClient.GetSecretAsync("https://play9VaultDemo.vault.azure.net/secrets/AppSecret")
                .ConfigureAwait(false);
            Message = secret.Value;

            /* The below do while logic is to handle throttling errors thrown by Azure Key Vault. It shows how to do exponential backoff which is the recommended client side throttling*/
            do
            {
                long waitTime = Math.Min(getWaitTime(retries), 2000000);
                secret = await keyVaultClient.GetSecretAsync("https://play9VaultDemo.vault.azure.net/secrets/AppSecret")
                    .ConfigureAwait(false);
                retry = false;
            }
            while (retry && (retries++ < 10));
        }
        /// <exception cref="KeyVaultErrorException">
        /// Thrown when the operation returned an invalid status code
        /// </exception>
        catch (KeyVaultErrorException keyVaultException)
        {
            Message = keyVaultException.Message;
            if ((int)keyVaultException.Response.StatusCode == 429)
                retry = true;
        }

But it says that access is forbidden when I try to access the secret. However if in Key Vault I give access to the System Assigned Identity of the Web application, I can access the secret,

Do you have any idea how can I make this work with the user assigned identity?

3

3 Answers

3
votes

Do you have any idea how can I make this work with the user assigned identity?

You could follow the steps from How to use managed identities for App Service and Azure Functions.

Here is the steps:

1.In webapp Identity, click User Assigned(preview) and add your user-assigned managed identity.

2.Adding the user-assigned type and a cotells Azure to create and manage the identity for your application using an Azure Resource Manager template.

"identity": {
        "type": "UserAssigned",
        "userAssignedIdentities": {
            "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', variables('identityName'))]": {}
        }
    }

3.If you request a token to Key Vault, you need to make sure you have added an access policy that includes your application's identity. Otherwise, your calls to Key Vault will be rejected, even if they include the token.

enter image description here

4.Using the Microsoft.Azure.Services.AppAuthentication library for .NET to get secret.

var azureServiceTokenProvider = new AzureServiceTokenProvider();
            var keyVaultClient = new KeyVaultClient(
               new KeyVaultClient.AuthenticationCallback(azureServiceTokenProvider.KeyVaultTokenCallback));

            var secret = keyVaultClient.GetSecretAsync("https://yourkeyvaultname.vault.azure.net/secrets/secretname").Result.Value;

5.The output is as below: enter image description here

8
votes

I had the same problem, and I had to do two things to step getting "forbidden" every time I tried to access KeyVault with a user-assigned identity:

  1. Upgrade the version of Microsoft.Azure.Services.AppAuthentication I was using to 1.2.0-preview2. Earlier versions don't have support for user-assigned identities.

  2. Pass a connection string into the AzureServiceTokenProvider constructor to tell the service which identity to use. This is the bit that all of the links above omit. So I had:

    var connectionString = "RunAs=App;AppId=";
    var azureServiceTokenProvider = new AzureServiceTokenProvider(connectionString);

instead of:

var azureServiceTokenProvider = new AzureServiceTokenProvider();

To find the value for your clientId, open up your managed identity in the Azure Portal. You should see a field marked "Client ID". That's the one you want.

1
votes

If you run into this error Connection string is not valid. Must contain 'TenantId' then make sure you explicitly reference Microsoft.Azure.Services.AppAuthentication >= v1.2.0

I was using Microsoft.Extensions.Configuration.AzureKeyVault v3.1.3 which ships with a lower version of AppAuthentication so user assigned identities didn't work.

More info here: https://github.com/MicrosoftDocs/azure-docs/issues/28729