Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accessing KeyVault with User-Assigned Managed Identity #2100

Closed
Kruti-Joshi opened this issue Nov 12, 2021 · 3 comments
Closed

Accessing KeyVault with User-Assigned Managed Identity #2100

Kruti-Joshi opened this issue Nov 12, 2021 · 3 comments
Assignees
Labels

Comments

@Kruti-Joshi
Copy link

Kruti-Joshi commented Nov 12, 2021

I tried giving access to my function app's user-assigned identiy to Azure KeyVault to fetch secrets, but kept getting an exception
"MSI authentication failed".

I'm using .Net Core 3.1 in the Azure function and am using the below code to fetch the secrets -

        `string secretQuery = request.Query["SecretName"];
        List<string> secretsList = secretQuery.Split(',').ToList();
        var kvName = Environment.GetEnvironmentVariable("KeyVaultName");
        var kvClient = new SecretClient(new Uri($"https://{kvName}.vault.azure.net"), new DefaultAzureCredential());
        Dictionary<string, string> secretResponse = new Dictionary<string, string>();

        foreach (string secretName in secretsList)
        {
            try
            {
                var secretValue = (await kvClient.GetSecretAsync(keyName)).Value.Value;
                secretResponse.Add(secretName, secretValue);
            }
            catch (Azure.RequestFailedException ex)
            {
                log.LogError($"Failed to fetch value for {secretName} from KeyVault - {ex.Message}. Inner Exception - {ex.InnerException}.");
                throw;
            }
        }

        return new OkObjectResult(secretResponse);`

Using a user-assigned identity with the above code is giving me the following exception from the function -
Exception while executing function: GetSecretsFunction ManagedIdentityCredential authentication failed: Service request failed.
Status: 400 (Bad Request)

As you can see from the above code, I'm passing the secrets to fetch as a query parameter to the function, to keep it generic. This works perfectly with a System-Assigned managed identity.

I referred to these threads and documentation -

  1. Unable to Access Key Vault from Azure Functions using User Managed Identities #1795
  2. https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references
    and found that support for user-assigned identity has been added, but needs the following KeyVault reference to be added to the configuration settings of the function app -
    @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

So, in my function app configuration, I'll have the below key-value pair -
key: mysecret
value: @Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/)

using which I can access the secret in the function as
var secretValue = Environment.GetEnvironmentVariable("mysecret")

However, by using this, I will have to specify all the secrets that I may need to fetch as part of the function app configuration, can cannot have a generic function where secret names can be passed as query parameters and fetched dynamically. Is this understanding correct?
Is there any way to fetch secrets from KeyVault in Azure function where user-assigned identity is just used for authentication and secret names to fetch can be decided based on parameters?

I'd highly appreciate some quick inputs on this.

@v-bbalaiagar v-bbalaiagar self-assigned this Nov 16, 2021
@v-bbalaiagar
Copy link

Hi @Kruti-Joshi, Thank you for your feedback! We will check for the possibilities internally and update you with the findings.

@v-bbalaiagar
Copy link

Hi @Kruti-Joshi, Can you please check whether you follow the configuration steps are defined here - https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet
https://docs.microsoft.com/en-us/azure/app-service/overview-managed-identity?tabs=dotnet#asal
Hi @mattchenderson, Could you provide some feedback on this.

@Kruti-Joshi
Copy link
Author

I was able to use the User Assigned Managed Identity with dynamically passed secret names. The issue was that I was using the default constructor to create the key vault client, whereas for the user assigned MSI, I need to specify the client ID of the identity as well.
To provide the client ID, I just added a configuration value to my function app -
"AZURE_CLIENT_ID": <client-id of user-assigned identity>
Now, in my function code, DefaultAzureCredential() automatically uses this value of client ID to use user-assigned MSI.
var kvClient = new SecretClient(new Uri($"https://{kvName}.vault.azure.net"), new DefaultAzureCredential());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants