@azure/identity 2.0.4 → 2.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @azure/identity might be problematic. Click here for more details.

Files changed (26) hide show
  1. package/CHANGELOG.md +13 -2
  2. package/dist/index.js +81 -41
  3. package/dist/index.js.map +1 -1
  4. package/dist-esm/src/client/identityClient.js +1 -1
  5. package/dist-esm/src/client/identityClient.js.map +1 -1
  6. package/dist-esm/src/credentials/defaultAzureCredential.js +7 -9
  7. package/dist-esm/src/credentials/defaultAzureCredential.js.map +1 -1
  8. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js +5 -2
  9. package/dist-esm/src/credentials/managedIdentityCredential/appServiceMsi2017.js.map +1 -1
  10. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js +16 -7
  11. package/dist-esm/src/credentials/managedIdentityCredential/arcMsi.js.map +1 -1
  12. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js +11 -5
  13. package/dist-esm/src/credentials/managedIdentityCredential/cloudShellMsi.js.map +1 -1
  14. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js +10 -4
  15. package/dist-esm/src/credentials/managedIdentityCredential/fabricMsi.js.map +1 -1
  16. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js +11 -5
  17. package/dist-esm/src/credentials/managedIdentityCredential/imdsMsi.js.map +1 -1
  18. package/dist-esm/src/credentials/managedIdentityCredential/index.js +20 -8
  19. package/dist-esm/src/credentials/managedIdentityCredential/index.js.map +1 -1
  20. package/dist-esm/src/credentials/managedIdentityCredential/models.js.map +1 -1
  21. package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js +1 -1
  22. package/dist-esm/src/credentials/managedIdentityCredential/tokenExchangeMsi.js.map +1 -1
  23. package/dist-esm/src/index.js +1 -1
  24. package/dist-esm/src/index.js.map +1 -1
  25. package/package.json +1 -1
  26. package/types/identity.d.ts +60 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Release History
2
2
 
3
+ ## 2.1.0-beta.1 (2022-03-02)
4
+
5
+ ### Features Added
6
+
7
+ - Added support for specifying a custom `resourceId` when creating a `ManagedIdentityCredential` or `DefaultAzureCredential`.
8
+ - In some scenarios where a user-assigned managed identity is required, the identity may be known by an ARM resource ID, but not a client ID (such as when user-assigned identities are created using an ARM template). The `resourceId` option allows an app to select its managed identity by its ARM resource ID to support such scenarios.
9
+ - If `resourceId` is provided, the managed identity providers for Azure App Service (2017), Azure Arc, Azure Cloud Shell, Azure Service Fabric and Token Exchange authentication will log a warning since this parameter is not supported by the identity endpoints in those services. The authentication attempts will be sent, but the parameter will be ignored by the service.
10
+ - Added `clientId` to the optional parameters of the `ManagedIdentityCredential`.
11
+ - Updated the Troubleshoot guide to have error codes and error messages for the Identity Customer Service Support.
12
+
3
13
  ## 2.0.4 (2022-02-18)
4
14
 
5
15
  ### Bugs Fixed
@@ -72,8 +82,8 @@ useIdentityPlugin(cachePersistencePlugin);
72
82
  async function main() {
73
83
  const credential = new DeviceCodeCredential({
74
84
  tokenCachePersistenceOptions: {
75
- enabled: true
76
- }
85
+ enabled: true,
86
+ },
77
87
  });
78
88
  }
79
89
  ```
@@ -139,6 +149,7 @@ Azure Service Fabric support hasn't been added on the initial version 2 of Ident
139
149
  - We have also renamed the error `CredentialUnavailable` to `CredentialUnavailableError`, to align with the naming convention used for error classes in the Azure SDKs in JavaScript.
140
150
  - In v1 of Identity some `getToken` calls could resolve with `null` in the case the authentication request succeeded with a malformed output. In v2, issues with the `getToken` method will always throw errors.
141
151
  - Breaking changes to InteractiveBrowserCredential
152
+
142
153
  - The `InteractiveBrowserCredential` will use the [Auth Code Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow) with [PKCE](https://tools.ietf.org/html/rfc7636) rather than [Implicit Grant Flow](https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-implicit-grant-flow) to better support browsers with enhanced security restrictions. Learn how to migrate in the [migration guide](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/migration-v1-v2.md). Read more about the latest `InteractiveBrowserCredential` [here](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/interactive-browser-credential.md).
143
154
  - The default client ID used for `InteractiveBrowserCredential` was viable only in Node.js and not for the browser. Therefore, on v2 client ID is a required parameter when using this credential in browser apps.
144
155
  - Identity v2 also removes the `postLogoutRedirectUri` from the options to the constructor for `InteractiveBrowserCredential`. This option wasn't being used. Instead of using this option, use MSAL directly. For more information, see [Authenticating with the @azure/msal-browser Public Client](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/identity/identity/samples/AzureIdentityExamples.md#authenticating-with-the-azuremsal-browser-public-client).
package/dist/index.js CHANGED
@@ -368,7 +368,7 @@ function getIdentityClientAuthorityHost(options) {
368
368
  class IdentityClient extends coreClient.ServiceClient {
369
369
  constructor(options) {
370
370
  var _a;
371
- const packageDetails = `azsdk-js-identity/2.0.4`;
371
+ const packageDetails = `azsdk-js-identity/2.1.0-beta.1`;
372
372
  const userAgentPrefix = ((_a = options === null || options === void 0 ? void 0 : options.userAgentOptions) === null || _a === void 0 ? void 0 : _a.userAgentPrefix)
373
373
  ? `${options.userAgentOptions.userAgentPrefix} ${packageDetails}`
374
374
  : `${packageDetails}`;
@@ -2242,7 +2242,7 @@ function prepareRequestOptions$5(scopes, clientId) {
2242
2242
  * Defines how to determine whether the Azure App Service MSI is available, and also how to retrieve a token from the Azure App Service MSI.
2243
2243
  */
2244
2244
  const appServiceMsi2017 = {
2245
- async isAvailable(scopes) {
2245
+ async isAvailable({ scopes }) {
2246
2246
  const resource = mapScopesToResource(scopes);
2247
2247
  if (!resource) {
2248
2248
  logger$a.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
@@ -2256,7 +2256,10 @@ const appServiceMsi2017 = {
2256
2256
  return result;
2257
2257
  },
2258
2258
  async getToken(configuration, getTokenOptions = {}) {
2259
- const { identityClient, scopes, clientId } = configuration;
2259
+ const { identityClient, scopes, clientId, resourceId } = configuration;
2260
+ if (resourceId) {
2261
+ logger$a.warning(`${msiName$5}: managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
2262
+ }
2260
2263
  logger$a.info(`${msiName$5}: Using the endpoint and the secret coming form the environment variables: MSI_ENDPOINT=${process.env.MSI_ENDPOINT} and MSI_SECRET=[REDACTED].`);
2261
2264
  const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$5(scopes, clientId)), {
2262
2265
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
@@ -2272,7 +2275,7 @@ const logger$9 = credentialLogger(msiName$4);
2272
2275
  /**
2273
2276
  * Generates the options used on the request for an access token.
2274
2277
  */
2275
- function prepareRequestOptions$4(scopes, clientId) {
2278
+ function prepareRequestOptions$4(scopes, clientId, resourceId) {
2276
2279
  const resource = mapScopesToResource(scopes);
2277
2280
  if (!resource) {
2278
2281
  throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
@@ -2283,6 +2286,9 @@ function prepareRequestOptions$4(scopes, clientId) {
2283
2286
  if (clientId) {
2284
2287
  body.client_id = clientId;
2285
2288
  }
2289
+ if (resourceId) {
2290
+ body.msi_res_id = resourceId;
2291
+ }
2286
2292
  // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2287
2293
  if (!process.env.MSI_ENDPOINT) {
2288
2294
  throw new Error(`${msiName$4}: Missing environment variable: MSI_ENDPOINT`);
@@ -2304,7 +2310,7 @@ function prepareRequestOptions$4(scopes, clientId) {
2304
2310
  * Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
2305
2311
  */
2306
2312
  const cloudShellMsi = {
2307
- async isAvailable(scopes) {
2313
+ async isAvailable({ scopes }) {
2308
2314
  const resource = mapScopesToResource(scopes);
2309
2315
  if (!resource) {
2310
2316
  logger$9.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
@@ -2317,12 +2323,15 @@ const cloudShellMsi = {
2317
2323
  return result;
2318
2324
  },
2319
2325
  async getToken(configuration, getTokenOptions = {}) {
2320
- const { identityClient, scopes, clientId } = configuration;
2326
+ const { identityClient, scopes, clientId, resourceId } = configuration;
2321
2327
  if (clientId) {
2322
- logger$9.warning(`${msiName$4}: does not support user-assigned identities in the Cloud Shell environment. Argument clientId will be ignored.`);
2328
+ logger$9.warning(`${msiName$4}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
2329
+ }
2330
+ if (resourceId) {
2331
+ logger$9.warning(`${msiName$4}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
2323
2332
  }
2324
2333
  logger$9.info(`${msiName$4}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
2325
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId)), {
2334
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
2326
2335
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
2327
2336
  allowInsecureConnection: true }));
2328
2337
  const tokenResponse = await identityClient.sendTokenRequest(request);
@@ -2353,7 +2362,7 @@ function expiresOnParser$1(requestBody) {
2353
2362
  /**
2354
2363
  * Generates the options used on the request for an access token.
2355
2364
  */
2356
- function prepareRequestOptions$3(scopes, clientId, options) {
2365
+ function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
2357
2366
  var _a;
2358
2367
  const resource = mapScopesToResource(scopes);
2359
2368
  if (!resource) {
@@ -2371,6 +2380,9 @@ function prepareRequestOptions$3(scopes, clientId, options) {
2371
2380
  if (clientId) {
2372
2381
  queryParameters.client_id = clientId;
2373
2382
  }
2383
+ if (resourceId) {
2384
+ queryParameters.msi_res_id = resourceId;
2385
+ }
2374
2386
  const params = new URLSearchParams(queryParameters);
2375
2387
  query = `?${params.toString()}`;
2376
2388
  }
@@ -2400,7 +2412,7 @@ const imdsMsiRetryConfig = {
2400
2412
  * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
2401
2413
  */
2402
2414
  const imdsMsi = {
2403
- async isAvailable(scopes, identityClient, clientId, getTokenOptions) {
2415
+ async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions, }) {
2404
2416
  var _a, _b;
2405
2417
  const resource = mapScopesToResource(scopes);
2406
2418
  if (!resource) {
@@ -2412,7 +2424,10 @@ const imdsMsi = {
2412
2424
  if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
2413
2425
  return true;
2414
2426
  }
2415
- const requestOptions = prepareRequestOptions$3(resource, clientId, {
2427
+ if (!identityClient) {
2428
+ throw new Error("Missing IdentityClient");
2429
+ }
2430
+ const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
2416
2431
  skipMetadataHeader: true,
2417
2432
  skipQuery: true,
2418
2433
  });
@@ -2465,12 +2480,12 @@ const imdsMsi = {
2465
2480
  }
2466
2481
  },
2467
2482
  async getToken(configuration, getTokenOptions = {}) {
2468
- const { identityClient, scopes, clientId } = configuration;
2483
+ const { identityClient, scopes, clientId, resourceId } = configuration;
2469
2484
  logger$8.info(`${msiName$3}: Using the Azure IMDS endpoint coming from the environment variable MSI_ENDPOINT=${process.env.MSI_ENDPOINT}, and using the cloud shell to proceed with the authentication.`);
2470
2485
  let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
2471
2486
  for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
2472
2487
  try {
2473
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId)), { allowInsecureConnection: true }));
2488
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
2474
2489
  const tokenResponse = await identityClient.sendTokenRequest(request, expiresOnParser$1);
2475
2490
  return (tokenResponse && tokenResponse.accessToken) || null;
2476
2491
  }
@@ -2493,7 +2508,7 @@ const logger$7 = credentialLogger(msiName$2);
2493
2508
  /**
2494
2509
  * Generates the options used on the request for an access token.
2495
2510
  */
2496
- function prepareRequestOptions$2(scopes) {
2511
+ function prepareRequestOptions$2(scopes, clientId, resourceId) {
2497
2512
  const resource = mapScopesToResource(scopes);
2498
2513
  if (!resource) {
2499
2514
  throw new Error(`${msiName$2}: Multiple scopes are not supported.`);
@@ -2502,11 +2517,17 @@ function prepareRequestOptions$2(scopes) {
2502
2517
  resource,
2503
2518
  "api-version": azureArcAPIVersion,
2504
2519
  };
2505
- const query = new URLSearchParams(queryParameters);
2520
+ if (clientId) {
2521
+ queryParameters.client_id = clientId;
2522
+ }
2523
+ if (resourceId) {
2524
+ queryParameters.msi_res_id = resourceId;
2525
+ }
2506
2526
  // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2507
2527
  if (!process.env.IDENTITY_ENDPOINT) {
2508
2528
  throw new Error(`${msiName$2}: Missing environment variable: IDENTITY_ENDPOINT`);
2509
2529
  }
2530
+ const query = new URLSearchParams(queryParameters);
2510
2531
  return coreRestPipeline.createPipelineRequest({
2511
2532
  // Should be similar to: http://localhost:40342/metadata/identity/oauth2/token
2512
2533
  url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
@@ -2553,7 +2574,7 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
2553
2574
  * Defines how to determine whether the Azure Arc MSI is available, and also how to retrieve a token from the Azure Arc MSI.
2554
2575
  */
2555
2576
  const arcMsi = {
2556
- async isAvailable(scopes) {
2577
+ async isAvailable({ scopes }) {
2557
2578
  const resource = mapScopesToResource(scopes);
2558
2579
  if (!resource) {
2559
2580
  logger$7.info(`${msiName$2}: Unavailable. Multiple scopes are not supported.`);
@@ -2567,12 +2588,15 @@ const arcMsi = {
2567
2588
  },
2568
2589
  async getToken(configuration, getTokenOptions = {}) {
2569
2590
  var _a;
2570
- const { identityClient, scopes, clientId } = configuration;
2571
- logger$7.info(`${msiName$2}: Authenticating.`);
2591
+ const { identityClient, scopes, clientId, resourceId } = configuration;
2572
2592
  if (clientId) {
2573
- throw new Error(`${msiName$2}: User assigned identity is not supported by the Azure Arc Managed Identity Endpoint. To authenticate with the system assigned identity, omit the client id when constructing the ManagedIdentityCredential, or if authenticating with the DefaultAzureCredential ensure the AZURE_CLIENT_ID environment variable is not set.`);
2593
+ logger$7.warning(`${msiName$2}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
2594
+ }
2595
+ if (resourceId) {
2596
+ logger$7.warning(`${msiName$2}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
2574
2597
  }
2575
- const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes)), { allowInsecureConnection: true });
2598
+ logger$7.info(`${msiName$2}: Authenticating.`);
2599
+ const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
2576
2600
  const filePath = await filePathRequest(identityClient, requestOptions);
2577
2601
  if (!filePath) {
2578
2602
  throw new Error(`${msiName$2}: Failed to find the token file.`);
@@ -2641,7 +2665,7 @@ function tokenExchangeMsi() {
2641
2665
  return azureFederatedTokenFileContent;
2642
2666
  }
2643
2667
  return {
2644
- async isAvailable(_scopes, _identityClient, clientId) {
2668
+ async isAvailable({ clientId }) {
2645
2669
  const env = process.env;
2646
2670
  const result = Boolean((clientId || env.AZURE_CLIENT_ID) && env.AZURE_TENANT_ID && azureFederatedTokenFilePath);
2647
2671
  if (!result) {
@@ -2691,7 +2715,7 @@ function expiresOnParser(requestBody) {
2691
2715
  /**
2692
2716
  * Generates the options used on the request for an access token.
2693
2717
  */
2694
- function prepareRequestOptions(scopes, clientId) {
2718
+ function prepareRequestOptions(scopes, clientId, resourceId) {
2695
2719
  const resource = mapScopesToResource(scopes);
2696
2720
  if (!resource) {
2697
2721
  throw new Error(`${msiName}: Multiple scopes are not supported.`);
@@ -2703,6 +2727,9 @@ function prepareRequestOptions(scopes, clientId) {
2703
2727
  if (clientId) {
2704
2728
  queryParameters.client_id = clientId;
2705
2729
  }
2730
+ if (resourceId) {
2731
+ queryParameters.msi_res_id = resourceId;
2732
+ }
2706
2733
  const query = new URLSearchParams(queryParameters);
2707
2734
  // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2708
2735
  if (!process.env.IDENTITY_ENDPOINT) {
@@ -2724,7 +2751,7 @@ function prepareRequestOptions(scopes, clientId) {
2724
2751
  * Defines how to determine whether the Azure Service Fabric MSI is available, and also how to retrieve a token from the Azure Service Fabric MSI.
2725
2752
  */
2726
2753
  const fabricMsi = {
2727
- async isAvailable(scopes) {
2754
+ async isAvailable({ scopes }) {
2728
2755
  const resource = mapScopesToResource(scopes);
2729
2756
  if (!resource) {
2730
2757
  logger$5.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
@@ -2738,7 +2765,10 @@ const fabricMsi = {
2738
2765
  return result;
2739
2766
  },
2740
2767
  async getToken(configuration, getTokenOptions = {}) {
2741
- const { scopes, identityClient, clientId } = configuration;
2768
+ const { scopes, identityClient, clientId, resourceId } = configuration;
2769
+ if (resourceId) {
2770
+ logger$5.warning(`${msiName}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
2771
+ }
2742
2772
  logger$5.info([
2743
2773
  `${msiName}:`,
2744
2774
  "Using the endpoint and the secret coming from the environment variables:",
@@ -2746,7 +2776,7 @@ const fabricMsi = {
2746
2776
  "IDENTITY_HEADER=[REDACTED] and",
2747
2777
  "IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
2748
2778
  ].join(" "));
2749
- const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId)));
2779
+ const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)));
2750
2780
  request.agent = new https__default["default"].Agent({
2751
2781
  // This is necessary because Service Fabric provides a self-signed certificate.
2752
2782
  // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
@@ -2773,44 +2803,56 @@ class ManagedIdentityCredential {
2773
2803
  * @hidden
2774
2804
  */
2775
2805
  constructor(clientIdOrOptions, options) {
2806
+ var _a, _b;
2776
2807
  this.isEndpointUnavailable = null;
2777
2808
  let _options;
2778
2809
  if (typeof clientIdOrOptions === "string") {
2779
- // clientId, options constructor
2780
2810
  this.clientId = clientIdOrOptions;
2781
2811
  _options = options;
2782
2812
  }
2783
2813
  else {
2784
- // options only constructor
2814
+ this.clientId = (_a = clientIdOrOptions) === null || _a === void 0 ? void 0 : _a.clientId;
2785
2815
  _options = clientIdOrOptions;
2786
2816
  }
2817
+ this.resourceId = (_b = _options) === null || _b === void 0 ? void 0 : _b.resourceId;
2818
+ // For JavaScript users.
2819
+ if (this.clientId && this.resourceId) {
2820
+ throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
2821
+ }
2787
2822
  this.identityClient = new IdentityClient(_options);
2788
2823
  this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
2789
2824
  maxRetries: 0,
2790
2825
  } }));
2791
2826
  }
2792
- async cachedAvailableMSI(scopes, clientId, getTokenOptions) {
2827
+ async cachedAvailableMSI(scopes, getTokenOptions) {
2793
2828
  if (this.cachedMSI) {
2794
2829
  return this.cachedMSI;
2795
2830
  }
2796
2831
  const MSIs = [fabricMsi, appServiceMsi2017, cloudShellMsi, arcMsi, tokenExchangeMsi(), imdsMsi];
2797
2832
  for (const msi of MSIs) {
2798
- if (await msi.isAvailable(scopes, this.isAvailableIdentityClient, clientId, getTokenOptions)) {
2833
+ if (await msi.isAvailable({
2834
+ scopes,
2835
+ identityClient: this.isAvailableIdentityClient,
2836
+ clientId: this.clientId,
2837
+ resourceId: this.resourceId,
2838
+ getTokenOptions,
2839
+ })) {
2799
2840
  this.cachedMSI = msi;
2800
2841
  return msi;
2801
2842
  }
2802
2843
  }
2803
2844
  throw new CredentialUnavailableError(`${ManagedIdentityCredential.name} - No MSI credential available`);
2804
2845
  }
2805
- async authenticateManagedIdentity(scopes, clientId, getTokenOptions) {
2846
+ async authenticateManagedIdentity(scopes, getTokenOptions) {
2806
2847
  const { span, updatedOptions } = createSpan(`${ManagedIdentityCredential.name}.authenticateManagedIdentity`, getTokenOptions);
2807
2848
  try {
2808
2849
  // Determining the available MSI, and avoiding checking for other MSIs while the program is running.
2809
- const availableMSI = await this.cachedAvailableMSI(scopes, clientId, updatedOptions);
2850
+ const availableMSI = await this.cachedAvailableMSI(scopes, updatedOptions);
2810
2851
  return availableMSI.getToken({
2811
2852
  identityClient: this.identityClient,
2812
2853
  scopes,
2813
- clientId,
2854
+ clientId: this.clientId,
2855
+ resourceId: this.resourceId,
2814
2856
  }, updatedOptions);
2815
2857
  }
2816
2858
  catch (err) {
@@ -2841,7 +2883,7 @@ class ManagedIdentityCredential {
2841
2883
  // If it's null, it means we don't yet know whether
2842
2884
  // the endpoint is available and need to check for it.
2843
2885
  if (this.isEndpointUnavailable !== true) {
2844
- result = await this.authenticateManagedIdentity(scopes, this.clientId, updatedOptions);
2886
+ result = await this.authenticateManagedIdentity(scopes, updatedOptions);
2845
2887
  if (result === null) {
2846
2888
  // If authenticateManagedIdentity returns null,
2847
2889
  // it means no MSI endpoints are available.
@@ -2929,14 +2971,12 @@ class ManagedIdentityCredential {
2929
2971
  */
2930
2972
  class DefaultManagedIdentityCredential extends ManagedIdentityCredential {
2931
2973
  constructor(options) {
2932
- var _a;
2933
- const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
2934
- if (managedIdentityClientId !== undefined) {
2935
- super(managedIdentityClientId, options);
2936
- }
2937
- else {
2938
- super(options);
2939
- }
2974
+ var _a, _b, _c;
2975
+ const managedIdentityClientId = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
2976
+ const managedResourceId = (_c = options) === null || _c === void 0 ? void 0 : _c.managedIdentityResourceId;
2977
+ // ManagedIdentityCredential throws if both the resourceId and the clientId are provided.
2978
+ const managedIdentityOptions = Object.assign({ resourceId: managedResourceId, clientId: managedIdentityClientId }, options);
2979
+ super(managedIdentityOptions);
2940
2980
  }
2941
2981
  }
2942
2982
  const defaultCredentials = [