Azure / azure-sdk-for-js

This repository is for active development of the Azure SDK for JavaScript (NodeJS & Browser). For consumers of the SDK we recommend visiting our public developer docs at https://docs.microsoft.com/javascript/azure/ or our versioned developer docs at https://azure.github.io/azure-sdk-for-js.
MIT License
2.08k stars 1.2k forks source link

DefaultAzureCredential fails for Container App Job #31080

Closed Makoehle closed 1 month ago

Makoehle commented 1 month ago

Describe the bug According to authenticating a user assigned manged identity the simple usage of DefaultAzureCredential() should allow infrastructure hosted on Azure to obtain the desired identity. Using this approach with Azure Container Instances works fine. But it fails with Container App Job.

To Reproduce Steps to reproduce the behavior:

  1. NodeJS app using the SDK and DefaultAzureCredential.
  2. Create a Container App Job and assign it a UserAssigned identity.
  3. Run the Container App Job

I assume I've got to use another flow but it's not clear from documentation which one is correct.

Expected behavior I expect no Exception to be thrown. I expect my container app job to assume the user assigned managed identity in order to access other Azure Resources.

Additional context

I compared the latest SDK version https://github.com/Azure/azure-sdk-for-js/compare/%40azure/identity_4.4.1...%40azure/identity_4.3.0 but appearently there are no changes so I assume it's not related to the minor diff in versions.

Identity show output az containerapp job identity show --name ***-***-*** { "type": "UserAssigned", "userAssignedIdentities": { "/subscriptions/**4b****-****-****-****-****389081**/resourcegroups/***-***-**/providers/Microsoft.ManagedIdentity/userAssignedIdentities/***-***-***-identity": { "clientId": "****6724-****-****-****-****c13c0895", "principalId": "****2f09-****-****-****-****5e6d4252" } } }
Logs /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3355 const err = new AggregateAuthenticationError(errors, "ChainedTokenCredential authentication failed."); ^   AggregateAuthenticationError: ChainedTokenCredential authentication failed. CredentialUnavailableError: EnvironmentCredential is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot. CredentialUnavailableError: WorkloadIdentityCredential: is unavailable. tenantId, clientId, and federatedTokenFilePath are required parameters. In DefaultAzureCredential and ManagedIdentityCredential, these can be provided as environment variables - "AZURE_TENANT_ID", "AZURE_CLIENT_ID", "AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot CredentialUnavailableError: ManagedIdentityCredential: The managed identity endpoint is indicating there's no available identity. Message: undefined Status code: 400 More details: undefined CredentialUnavailableError: Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'. CredentialUnavailableError: Error: Unable to execute PowerShell. Ensure that it is installed in your system. To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot. CredentialUnavailableError: Azure Developer CLI couldn't be found. To mitigate this issue, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot. at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3355:29 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async DefaultAzureCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3330:27) at async tryGetAccessToken (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:36:32) at async beginRefresh (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:44:17) at async Object.defaultAuthorizeRequest [as authorizeRequest] (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:21:25) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:72:13) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/redirectPolicy.js:25:30) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+storage-queue@12.22.0/node_modules/@azure/storage-queue/dist/index.js:1663:32) { errors: [ CredentialUnavailableError: EnvironmentCredential is unavailable. No underlying credential could be used. To troubleshoot, visit https://aka.ms/azsdk/js/identity/environmentcredential/troubleshoot. at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3681:19 at /srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:114 at Object.withContext (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/instrumenter.js:41:20) at withContext (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:49:57) at Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:34) at EnvironmentCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3665:30) at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3340:52 at /srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:114 at Object.withContext (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/instrumenter.js:41:20) at withContext (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:49:57), CredentialUnavailableError: WorkloadIdentityCredential: is unavailable. tenantId, clientId, and federatedTokenFilePath are required parameters. In DefaultAzureCredential and ManagedIdentityCredential, these can be provided as environment variables - "AZURE_TENANT_ID", "AZURE_CLIENT_ID", "AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot at WorkloadIdentityCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:2364:19) at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3340:52 at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async DefaultAzureCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3330:27) at async tryGetAccessToken (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:36:32) at async beginRefresh (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:44:17) at async Object.defaultAuthorizeRequest [as authorizeRequest] (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:21:25) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:72:13) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/redirectPolicy.js:25:30) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+storage-queue@12.22.0/node_modules/@azure/storage-queue/dist/index.js:1663:32), CredentialUnavailableError: ManagedIdentityCredential: The managed identity endpoint is indicating there's no available identity. Message: undefined Status code: 400 More details: undefined at ManagedIdentityCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:2629:23) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3340:29 at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async DefaultAzureCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3330:27) at async tryGetAccessToken (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:36:32) at async beginRefresh (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:44:17) at async Object.defaultAuthorizeRequest [as authorizeRequest] (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:21:25) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:72:13) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/redirectPolicy.js:25:30), CredentialUnavailableError: Azure CLI could not be found. Please visit https://aka.ms/azure-cli for installation instructions and then, once installed, authenticate to your Azure account using 'az login'. at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:2849:35 at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3340:29 at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async DefaultAzureCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3330:27) at async tryGetAccessToken (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:36:32) at async beginRefresh (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:44:17) at async Object.defaultAuthorizeRequest [as authorizeRequest] (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:21:25) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:72:13) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/redirectPolicy.js:25:30), CredentialUnavailableError: Error: Unable to execute PowerShell. Ensure that it is installed in your system. To troubleshoot, visit https://aka.ms/azsdk/js/identity/powershellcredential/troubleshoot. at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3281:31 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3340:29 at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async DefaultAzureCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3330:27) at async tryGetAccessToken (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:36:32) at async beginRefresh (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:44:17) at async Object.defaultAuthorizeRequest [as authorizeRequest] (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:21:25) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:72:13), CredentialUnavailableError: Azure Developer CLI couldn't be found. To mitigate this issue, see the troubleshooting guidelines at https://aka.ms/azsdk/js/identity/azdevclicredential/troubleshoot. at /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3045:35 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async /srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3340:29 at async Object.withSpan (/srv/dist/node_modules/.pnpm/@azure+core-tracing@1.1.2/node_modules/@azure/core-tracing/dist/commonjs/tracingClient.js:36:28) at async DefaultAzureCredential.getToken (/srv/dist/node_modules/.pnpm/@azure+identity@4.3.0/node_modules/@azure/identity/dist/index.js:3330:27) at async tryGetAccessToken (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:36:32) at async beginRefresh (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/util/tokenCycler.js:44:17) at async Object.defaultAuthorizeRequest [as authorizeRequest] (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:21:25) at async Object.sendRequest (/srv/dist/node_modules/.pnpm/@azure+core-rest-pipeline@1.16.1/node_modules/@azure/core-rest-pipeline/dist/commonjs/policies/bearerTokenAuthenticationPolicy.js:72:13) ] }   Node.js v20.13.1
github-actions[bot] commented 1 month ago

@KarishmaGhiya @maorleger

github-actions[bot] commented 1 month ago

Thank you for your feedback. Tagging and routing to the team member best able to assist.

maorleger commented 1 month ago

Hiya @Makoehle - thanks for opening this issue. We'd love to help, but need more information from you. Could you enable verbose logging and provide the output?

The error shows ManagedIdentityCredential: The managed identity endpoint is indicating there's no available identity which means it is unable to find the managed identity you expect.

I wonder, are you passing in the clientId? For user-assigned managed identities I usually expect to see something like:

  // if using DefaultAzureCredential
  const defaultAzureCredential = new DefaultAzureCredential({
    managedIdentityClientId: "<my_client_id>"
  })

  // if using ManagedIdentityCredential
  const managedIdentity = new ManagedIdentityCredential({
    clientId: "<my_client_id>"
  })

Or of course the AZURE_CLIENT_ID and AZURE_TENANT_ID environment variables if you're using DefaultAzureCredential. The logs should show, but I would confirm that AZURE_CLIENT_ID env var is what you expect the value to be.

As a debugging tip, consider using ManagedIdentityCredential directly if you know you only need managed identity at least while debugging if not permanently. DefaultAzureCredential is convenient, but the amount of logs it prints out can be obnoxious 😄

Let me know if any of these tips worked, and if not please do share the verbose logs so we can better understand the issue.

github-actions[bot] commented 1 month ago

Hi @Makoehle. Thank you for opening this issue and giving us the opportunity to assist. To help our team better understand your issue and the details of your scenario please provide a response to the question asked above or the information requested above. This will help us more accurately address your issue.

Makoehle commented 1 month ago

Hi @maorleger - Thank you for the support. Adding managedIdentityClientId: "<my_client_id>" did the trick. My expectation was that this is handled automatically because using new DefaultAzureCredential() in an Azure Container Instance works just fine in another service of mine. Anyway it works locally with AzCli now, where I simply omit the ID and on Azure where I provide it. For that reason I close the issue. Again Thank you.

maorleger commented 1 month ago

Glad to hear it, although if you wanted to dig into it a bit you could make sure that AZURE_CLIENT_ID environment variable is set to the value you expect it to. It might be as simple as console.log(process.env.AZURE_CLIENT_ID) and tweaking your environment config until it shows what you expect. If you got that far and DefaultAzureCredential still does not pick up the environment variable I'd love to hear about it!

Either way, glad you are unblocked 😄