wangzhibo
2026-05-09 53418655c061ac26f66058253f39200aced1ab1d
1
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions, TokenCredential } from \"@azure/core-auth\";\n\nimport type { TokenCredentialOptions } from \"../../tokenCredentialOptions.js\";\nimport { getLogLevel } from \"@azure/logger\";\nimport { ManagedIdentityApplication } from \"@azure/msal-node\";\nimport { IdentityClient } from \"../../client/identityClient.js\";\nimport { AuthenticationRequiredError, CredentialUnavailableError } from \"../../errors.js\";\nimport { getMSALLogLevel, defaultLoggerCallback } from \"../../msal/utils.js\";\nimport { imdsRetryPolicy } from \"./imdsRetryPolicy.js\";\nimport type { MSIConfiguration } from \"./models.js\";\nimport { formatSuccess, formatError, credentialLogger } from \"../../util/logging.js\";\nimport { tracingClient } from \"../../util/tracing.js\";\nimport { imdsMsi } from \"./imdsMsi.js\";\nimport { tokenExchangeMsi } from \"./tokenExchangeMsi.js\";\nimport { mapScopesToResource, serviceFabricErrorMessage } from \"./utils.js\";\nimport type { MsalToken, ValidMsalToken } from \"../../msal/types.js\";\nimport type {\n  InternalManagedIdentityCredentialOptions,\n  ManagedIdentityCredentialClientIdOptions,\n  ManagedIdentityCredentialObjectIdOptions,\n  ManagedIdentityCredentialResourceIdOptions,\n} from \"./options.js\";\n\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\n/**\n * Attempts authentication using a managed identity available at the deployment environment.\n * This authentication type works in Azure VMs, App Service instances, Azure Functions applications,\n * Azure Kubernetes Services, Azure Service Fabric instances and inside of the Azure Cloud Shell.\n *\n * More information about configuring managed identities can be found here:\n * https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview\n */\nexport class ManagedIdentityCredential implements TokenCredential {\n  private managedIdentityApp: ManagedIdentityApplication;\n  private identityClient: IdentityClient;\n  private clientId?: string;\n  private resourceId?: string;\n  private objectId?: string;\n  private msiRetryConfig: MSIConfiguration[\"retryConfig\"] = {\n    maxRetries: 5,\n    startDelayInMs: 800,\n    intervalIncrement: 2,\n  };\n  private isAvailableIdentityClient: IdentityClient;\n  private sendProbeRequest: boolean;\n\n  /**\n   * Creates an instance of ManagedIdentityCredential with the client ID of a\n   * user-assigned identity, or app registration (when working with AKS pod-identity).\n   *\n   * @param clientId - The client ID of the user-assigned identity, or app registration (when working with AKS pod-identity).\n   * @param options - Options for configuring the client which makes the access token request.\n   */\n  constructor(clientId: string, options?: TokenCredentialOptions);\n  /**\n   * Creates an instance of ManagedIdentityCredential with a client ID\n   *\n   * @param options - Options for configuring the client which makes the access token request.\n   */\n  constructor(options?: ManagedIdentityCredentialClientIdOptions);\n  /**\n   * Creates an instance of ManagedIdentityCredential with a resource ID\n   *\n   * @param options - Options for configuring the resource which makes the access token request.\n   */\n  constructor(options?: ManagedIdentityCredentialResourceIdOptions);\n  /**\n   * Creates an instance of ManagedIdentityCredential with an object ID\n   *\n   * @param options - Options for configuring the resource which makes the access token request.\n   */\n  constructor(options?: ManagedIdentityCredentialObjectIdOptions);\n  /**\n   * @internal\n   * @hidden\n   */\n  constructor(\n    clientIdOrOptions?:\n      | string\n      | ManagedIdentityCredentialClientIdOptions\n      | ManagedIdentityCredentialResourceIdOptions\n      | ManagedIdentityCredentialObjectIdOptions,\n    options?: TokenCredentialOptions,\n  ) {\n    let _options: TokenCredentialOptions;\n    if (typeof clientIdOrOptions === \"string\") {\n      this.clientId = clientIdOrOptions;\n      _options = options ?? {};\n    } else {\n      this.clientId = (clientIdOrOptions as ManagedIdentityCredentialClientIdOptions)?.clientId;\n      _options = clientIdOrOptions ?? {};\n    }\n    this.resourceId = (_options as ManagedIdentityCredentialResourceIdOptions)?.resourceId;\n    this.objectId = (_options as ManagedIdentityCredentialObjectIdOptions)?.objectId;\n    this.sendProbeRequest =\n      (_options as InternalManagedIdentityCredentialOptions)?.sendProbeRequest ?? false;\n    // For JavaScript users.\n    const providedIds = [\n      { key: \"clientId\", value: this.clientId },\n      { key: \"resourceId\", value: this.resourceId },\n      { key: \"objectId\", value: this.objectId },\n    ].filter((id) => id.value);\n    if (providedIds.length > 1) {\n      throw new Error(\n        `ManagedIdentityCredential: only one of 'clientId', 'resourceId', or 'objectId' can be provided. Received values: ${JSON.stringify(\n          { clientId: this.clientId, resourceId: this.resourceId, objectId: this.objectId },\n        )}`,\n      );\n    }\n\n    // ManagedIdentity uses http for local requests\n    _options.allowInsecureConnection = true;\n\n    if (_options.retryOptions?.maxRetries !== undefined) {\n      this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;\n    }\n\n    this.identityClient = new IdentityClient({\n      ..._options,\n      additionalPolicies: [{ policy: imdsRetryPolicy(this.msiRetryConfig), position: \"perCall\" }],\n    });\n\n    this.managedIdentityApp = new ManagedIdentityApplication({\n      managedIdentityIdParams: {\n        userAssignedClientId: this.clientId,\n        userAssignedResourceId: this.resourceId,\n        userAssignedObjectId: this.objectId,\n      },\n      system: {\n        disableInternalRetries: true,\n        networkClient: this.identityClient,\n        loggerOptions: {\n          logLevel: getMSALLogLevel(getLogLevel()),\n          piiLoggingEnabled: _options.loggingOptions?.enableUnsafeSupportLogging,\n          loggerCallback: defaultLoggerCallback(logger),\n        },\n      },\n    });\n\n    this.isAvailableIdentityClient = new IdentityClient({\n      ..._options,\n      retryOptions: {\n        maxRetries: 0,\n      },\n    });\n\n    const managedIdentitySource = this.managedIdentityApp.getManagedIdentitySource();\n    // CloudShell MSI will ignore any user-assigned identity passed as parameters. To avoid confusion, we prevent this from happening as early as possible.\n    if (managedIdentitySource === \"CloudShell\") {\n      if (this.clientId || this.resourceId || this.objectId) {\n        logger.warning(\n          `CloudShell MSI detected with user-provided IDs - throwing. Received values: ${JSON.stringify(\n            {\n              clientId: this.clientId,\n              resourceId: this.resourceId,\n              objectId: this.objectId,\n            },\n          )}.`,\n        );\n        throw new CredentialUnavailableError(\n          \"ManagedIdentityCredential: Specifying a user-assigned managed identity is not supported for CloudShell at runtime. When using Managed Identity in CloudShell, omit the clientId, resourceId, and objectId parameters.\",\n        );\n      }\n    }\n\n    // ServiceFabric does not support specifying user-assigned managed identity by client ID or resource ID. The managed identity selected is based on the resource configuration.\n    if (managedIdentitySource === \"ServiceFabric\") {\n      if (this.clientId || this.resourceId || this.objectId) {\n        logger.warning(\n          `Service Fabric detected with user-provided IDs - throwing. Received values: ${JSON.stringify(\n            {\n              clientId: this.clientId,\n              resourceId: this.resourceId,\n              objectId: this.objectId,\n            },\n          )}.`,\n        );\n        throw new CredentialUnavailableError(\n          `ManagedIdentityCredential: ${serviceFabricErrorMessage}`,\n        );\n      }\n    }\n\n    logger.info(`Using ${managedIdentitySource} managed identity.`);\n\n    // Check if either clientId, resourceId or objectId was provided and log the value used\n    if (providedIds.length === 1) {\n      const { key, value } = providedIds[0];\n      logger.info(`${managedIdentitySource} with ${key}: ${value}`);\n    }\n  }\n\n  /**\n   * Authenticates with Microsoft Entra ID and returns an access token if successful.\n   * If authentication fails, a {@link CredentialUnavailableError} will be thrown with the details of the failure.\n   * If an unexpected error occurs, an {@link AuthenticationError} will be thrown with the details of the failure.\n   *\n   * @param scopes - The list of scopes for which the token will have access.\n   * @param options - The options used to configure any requests this\n   *                TokenCredential implementation might make.\n   */\n  public async getToken(\n    scopes: string | string[],\n    options: GetTokenOptions = {},\n  ): Promise<AccessToken> {\n    logger.getToken.info(\"Using the MSAL provider for Managed Identity.\");\n    const resource = mapScopesToResource(scopes);\n    if (!resource) {\n      throw new CredentialUnavailableError(\n        `ManagedIdentityCredential: Multiple scopes are not supported. Scopes: ${JSON.stringify(\n          scopes,\n        )}`,\n      );\n    }\n\n    return tracingClient.withSpan(\"ManagedIdentityCredential.getToken\", options, async () => {\n      try {\n        const isTokenExchangeMsi = await tokenExchangeMsi.isAvailable(this.clientId);\n\n        // Most scenarios are handled by MSAL except for two:\n        // AKS pod identity - MSAL does not implement the token exchange flow.\n        // IMDS Endpoint probing - MSAL does not do any probing before trying to get a token.\n        // As a DefaultAzureCredential optimization we probe the IMDS endpoint with a short timeout and no retries before actually trying to get a token\n        // We will continue to implement these features in the Identity library.\n\n        const identitySource = this.managedIdentityApp.getManagedIdentitySource();\n        const isImdsMsi = identitySource === \"DefaultToImds\" || identitySource === \"Imds\"; // Neither actually checks that IMDS endpoint is available, just that it's the source the MSAL _would_ try to use.\n\n        logger.getToken.info(`MSAL Identity source: ${identitySource}`);\n\n        if (isTokenExchangeMsi) {\n          // In the AKS scenario we will use the existing tokenExchangeMsi indefinitely.\n          logger.getToken.info(\"Using the token exchange managed identity.\");\n          const result = await tokenExchangeMsi.getToken({\n            scopes,\n            clientId: this.clientId,\n            identityClient: this.identityClient,\n            retryConfig: this.msiRetryConfig,\n            resourceId: this.resourceId,\n          });\n\n          if (result === null) {\n            throw new CredentialUnavailableError(\n              \"Attempted to use the token exchange managed identity, but received a null response.\",\n            );\n          }\n\n          return result;\n        } else if (isImdsMsi && this.sendProbeRequest) {\n          // In the IMDS scenario we will probe the IMDS endpoint to ensure it's available before trying to get a token.\n          // If the IMDS endpoint is not available and this is the source that MSAL will use, we will fail-fast with an error that tells DAC to move to the next credential.\n          logger.getToken.info(\"Using the IMDS endpoint to probe for availability.\");\n          const isAvailable = await imdsMsi.isAvailable({\n            scopes,\n            clientId: this.clientId,\n            getTokenOptions: options,\n            identityClient: this.isAvailableIdentityClient,\n            resourceId: this.resourceId,\n          });\n\n          if (!isAvailable) {\n            throw new CredentialUnavailableError(\n              `Attempted to use the IMDS endpoint, but it is not available.`,\n            );\n          }\n        }\n\n        // If we got this far, it means:\n        // - This is not a tokenExchangeMsi,\n        // - We already probed for IMDS endpoint availability and failed-fast if it's unreachable,\n        // or we skip probing because the credential is set in DAC.\n        // We can proceed normally by calling MSAL for a token.\n        logger.getToken.info(\"Calling into MSAL for managed identity token.\");\n        const token = await this.managedIdentityApp.acquireToken({\n          resource,\n        });\n\n        this.ensureValidMsalToken(scopes, token, options);\n        logger.getToken.info(formatSuccess(scopes));\n\n        return {\n          expiresOnTimestamp: token.expiresOn.getTime(),\n          token: token.accessToken,\n          refreshAfterTimestamp: token.refreshOn?.getTime(),\n          tokenType: \"Bearer\",\n        } as AccessToken;\n      } catch (err: any) {\n        logger.getToken.error(formatError(scopes, err));\n\n        // AuthenticationRequiredError described as Error to enforce authentication after trying to retrieve a token silently.\n        // TODO: why would this _ever_ happen considering we're not trying the silent request in this flow?\n        if (err.name === \"AuthenticationRequiredError\") {\n          throw err;\n        }\n\n        if (isNetworkError(err)) {\n          throw new CredentialUnavailableError(\n            `ManagedIdentityCredential: Network unreachable. Message: ${err.message}`,\n            { cause: err },\n          );\n        }\n\n        throw new CredentialUnavailableError(\n          `ManagedIdentityCredential: Authentication failed. Message ${err.message}`,\n          { cause: err },\n        );\n      }\n    });\n  }\n\n  /**\n   * Ensures the validity of the MSAL token\n   */\n  private ensureValidMsalToken(\n    scopes: string | string[],\n    msalToken?: MsalToken,\n    getTokenOptions?: GetTokenOptions,\n  ): asserts msalToken is ValidMsalToken {\n    const createError = (message: string): Error => {\n      logger.getToken.info(message);\n      return new AuthenticationRequiredError({\n        scopes: Array.isArray(scopes) ? scopes : [scopes],\n        getTokenOptions,\n        message,\n      });\n    };\n    if (!msalToken) {\n      throw createError(\"No response.\");\n    }\n    if (!msalToken.expiresOn) {\n      throw createError(`Response had no \"expiresOn\" property.`);\n    }\n    if (!msalToken.accessToken) {\n      throw createError(`Response had no \"accessToken\" property.`);\n    }\n  }\n}\n\nfunction isNetworkError(err: any): boolean {\n  // MSAL error\n  if (err.errorCode === \"network_error\") {\n    return true;\n  }\n\n  // Probe errors\n  if (err.code === \"ENETUNREACH\" || err.code === \"EHOSTUNREACH\") {\n    return true;\n  }\n\n  // This is a special case for Docker Desktop which responds with a 403 with a message that contains \"A socket operation was attempted to an unreachable network\" or \"A socket operation was attempted to an unreachable host\"\n  // rather than just timing out, as expected.\n  if (err.statusCode === 403 || err.code === 403) {\n    if (err.message.includes(\"unreachable\")) {\n      return true;\n    }\n  }\n\n  return false;\n}\n"]}