Reputation: 4150
My web application retrieves its secrets from our company's shared Azure Key Vault, and the permissions for that are granted via RBAC (role-based access control). This works great normally, but on my new computer I am getting the following error....
Exception thrown: 'Azure.Identity.AuthenticationFailedException' in System.Private.CoreLib.dll
An unhandled exception of type 'Azure.Identity.AuthenticationFailedException' occurred in System.Private.CoreLib.dll
ManagedIdentityCredential authentication failed: Access to the path 'C:\ProgramData\AzureConnectedMachineAgent\Tokens\20f36e17-204a-4e08-b190-bda27a9402cb.key' is denied.
The credentials instance is being loaded via the following code:
credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions()
{
VisualStudioTenantId = tenantId,
SharedTokenCacheTenantId = tenantId,
VisualStudioCodeTenantId = tenantId,
InteractiveBrowserTenantId = tenantId,
});
Strangely, this only happens on my new computer. My kneejerk response is to run VS2022 as administrator, but other developers are running it as themselves and are not having this issue.
Anyone run into this before?
Upvotes: 4
Views: 7989
Reputation: 13511
I'm posting this as an alternative solution for those who are running into this problem for the same reasons that the OP was running into them. Here are a few things to look at, as well as the documentation that might suggest why this unexpected behavior is happening and how you might also be able to control/manipulate it:
DefaultAzureCredential
attempts to check, where Managed Identity is #3 in that list (as of Feb 2024). This might help you understand what options are still options if you want to just rely on this order-of-operations to manipulate the situation.local.settings.json
, which is #1 in that order-of-operations list. I know you don't want to hardcode your secrets in there and you want to dynamically get them from KV, but that's still an option here. You could have a line that looks like this inside of your Values
object in there to dynamically pull the value at runtime for your dev environment. If you do this, be sure to also set AZURE_TENANT_ID
and AZURE_CLIENT_ID
for the client side of your handshakes. This will use your VS credentials to access KV, so there are still some permission things at play there (which is a good thing, but is a variable to consider). "AZURE_CLIENT_SECRET": "@Microsoft.KeyVault(VaultName=kv-name-goes-here;SecretName=secret-name-goes-here)",
Just to document the order-of-operations (in case URLs break or something), as of Feb 2024, DefaultAzureCredential
pulls things in this order (copied from the above link, source goes to learn.microsoft.com):
DefaultAzureCredential
will read account information specified via environment variables and use it to authenticate.DefaultAzureCredential
will authenticate with that account.DefaultAzureCredential
will authenticate with that account.DefaultAzureCredential
will authenticate with that account.VisualStudioCodeCredential
will be re-enabled in the DefaultAzureCredential
flow once a fix is in place. Issue #30525 tracks this. In the meantime Visual Studio Code users can authenticate their development environment using the Azure CLI.az login
command, the DefaultAzureCredential
will authenticate with that account.Connect-AzAccount
command, the DefaultAzureCredential
will authenticate with that account.azd auth login
command, the DefaultAzureCredential
will authenticate with that account.DefaultAzureCredential
will interactively authenticate the developer via the current system's default browser. By default, this credential type is disabled.Upvotes: 4
Reputation: 4150
I managed to resolve the error, at least in this instance, by excluding Managed Identity Credential from the list of sources when instantiating the DefaultAzureCredential class. You can do this via the DefaultAzureCredentialOptions class like so:
credentials = new DefaultAzureCredential(new DefaultAzureCredentialOptions()
{
VisualStudioTenantId = tenantId,
SharedTokenCacheTenantId = tenantId,
VisualStudioCodeTenantId = tenantId,
InteractiveBrowserTenantId = tenantId,
ExcludeManagedIdentityCredential = true // <-- added this line
});
Still not sure what actually causes the issue though.
Upvotes: 4