I had enabled system assigned managed identity in azure function(Service bus topic trigger) and added the identity(Object (principal) ID ) in key vault access policy with "Get,List" permissions of secrets, keys. I added the reference of the Key Vault into Azure function Application settings and able to receive at runtime after azure function deployment.
@Microsoft.KeyVault(SecretUri=https://myvault.vault.azure.net/secrets/mysecret/ec96f02080254f109c51a1f14cdb1931)
Code:
private async Task<string> FetchSecretValueFromKeyvault(string secretName)
{
_logger.LogInformation($"FetchSecretValueFromKeyvault: SecretName {secretName}");
string actualSecret = string.Empty;
try
{
string systemAssignedClientId = GetEnvironmentVariable("AzureADManagedIdentityClientId");
string azureKeyVaultUrl = GetEnvironmentVariable("AzureKeyVaultUrl");
var defaultAzureCredentialOptions = new DefaultAzureCredentialOptions();
defaultAzureCredentialOptions.ExcludeAzureCliCredential = true;
defaultAzureCredentialOptions.ExcludeEnvironmentCredential = true;
defaultAzureCredentialOptions.ExcludeAzurePowerShellCredential = true;
defaultAzureCredentialOptions.ExcludeInteractiveBrowserCredential = true;
defaultAzureCredentialOptions.ExcludeManagedIdentityCredential = false;
defaultAzureCredentialOptions.ExcludeSharedTokenCacheCredential = true;
defaultAzureCredentialOptions.ExcludeVisualStudioCodeCredential = true;
defaultAzureCredentialOptions.ExcludeVisualStudioCredential = true;
defaultAzureCredentialOptions.ManagedIdentityClientId = systemAssignedClientId;
var credential = new DefaultAzureCredential(defaultAzureCredentialOptions);
var client = new SecretClient(new Uri(AzureKeyVaultUrl)), credential);
var secret = await client.GetSecretAsync(secretName).ConfigureAwait(false);
actualSecret = secret.Value.Value;
_logger.LogInformation($"FetchSecretValueFromKeyvault: Received secretValue for {secretName}");
}
catch (RequestFailedException ex)
{
actualSecret = string.Empty;
_logger.LogError($"Message: {ex.Message}. \nInnerException:{ex.InnerException}. \nStackTrace: {ex.StackTrace}. \nInnerExceptionMessage:{ex.InnerException?.Message}.");
}
catch (Exception ex)
{
actualSecret = string.Empty;
_logger.LogError($"Message: {ex.Message}. \nInnerException:{ex.InnerException}. \nStackTrace: {ex.StackTrace}. \nInnerExceptionMessage:{ex.InnerException?.Message}.");
}
return actualSecret;
}
local settings & Azure Function App Settings:
"AzureADManagedIdentityClientId": "xxx-123-abc-xyz-567890"
"AzureKeyVaultUrl": "https://keyvaulturl.azurewebsites.net",
Nuget package and its versions:
Azure.Security.KeyVault.Secrets -- 4.3.0
Azure.Extensions.AspNetCore.Configuration.Secrets -- 1.2.2
Azure.Identity -- 1.6.1
Function Runtime Version: .NET Core V3.1
I am trying to read same secret value through code with help of same managed identity, I am getting error ManagedIdentityCredential authentication unavailable. Multiple attempts failed to obtain a token from the managed identity endpoint.'
while debugging in local machine. I deployed azure function and in application insights, I am getting No Managed Identity found for specified ClientId/ResourceId/PrincipalId. Status: 400 (Bad Request)
I double cross checked PrincipalId
, Its existed in both local seetings , azure function app settings and value is correct.
what am i doing wrong?