@azure/identity 4.1.0-alpha.20240327.2 → 4.1.0-alpha.20240409.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.

package/dist/index.js CHANGED
@@ -12,8 +12,8 @@ var fs = require('fs');
12
12
  var os = require('os');
13
13
  var path = require('path');
14
14
  var msalCommon = require('@azure/msal-node');
15
- var promises = require('fs/promises');
16
15
  var https = require('https');
16
+ var promises = require('fs/promises');
17
17
  var child_process = require('child_process');
18
18
  var crypto = require('crypto');
19
19
  var util = require('util');
@@ -1022,7 +1022,7 @@ const appServiceMsi2017 = {
1022
1022
 
1023
1023
  // Copyright (c) Microsoft Corporation.
1024
1024
  // Licensed under the MIT license.
1025
- const msiName$5 = "ManagedIdentityCredential - CloudShellMSI";
1025
+ const msiName$5 = "ManagedIdentityCredential - AppServiceMSI 2019";
1026
1026
  const logger$m = credentialLogger(msiName$5);
1027
1027
  /**
1028
1028
  * Generates the options used on the request for an access token.
@@ -1032,58 +1032,54 @@ function prepareRequestOptions$4(scopes, clientId, resourceId) {
1032
1032
  if (!resource) {
1033
1033
  throw new Error(`${msiName$5}: Multiple scopes are not supported.`);
1034
1034
  }
1035
- const body = {
1035
+ const queryParameters = {
1036
1036
  resource,
1037
+ "api-version": "2019-08-01",
1037
1038
  };
1038
1039
  if (clientId) {
1039
- body.client_id = clientId;
1040
+ queryParameters.client_id = clientId;
1040
1041
  }
1041
1042
  if (resourceId) {
1042
- body.msi_res_id = resourceId;
1043
+ queryParameters.mi_res_id = resourceId;
1043
1044
  }
1045
+ const query = new URLSearchParams(queryParameters);
1044
1046
  // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1045
- if (!process.env.MSI_ENDPOINT) {
1046
- throw new Error(`${msiName$5}: Missing environment variable: MSI_ENDPOINT`);
1047
+ if (!process.env.IDENTITY_ENDPOINT) {
1048
+ throw new Error(`${msiName$5}: Missing environment variable: IDENTITY_ENDPOINT`);
1049
+ }
1050
+ if (!process.env.IDENTITY_HEADER) {
1051
+ throw new Error(`${msiName$5}: Missing environment variable: IDENTITY_HEADER`);
1047
1052
  }
1048
- const params = new URLSearchParams(body);
1049
1053
  return {
1050
- url: process.env.MSI_ENDPOINT,
1051
- method: "POST",
1052
- body: params.toString(),
1054
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1055
+ method: "GET",
1053
1056
  headers: coreRestPipeline.createHttpHeaders({
1054
1057
  Accept: "application/json",
1055
- Metadata: "true",
1056
- "Content-Type": "application/x-www-form-urlencoded",
1058
+ "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
1057
1059
  }),
1058
1060
  };
1059
1061
  }
1060
1062
  /**
1061
- * Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
1062
- * 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.
1063
+ * 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.
1063
1064
  */
1064
- const cloudShellMsi = {
1065
- name: "cloudShellMsi",
1065
+ const appServiceMsi2019 = {
1066
+ name: "appServiceMsi2019",
1066
1067
  async isAvailable({ scopes }) {
1067
1068
  const resource = mapScopesToResource(scopes);
1068
1069
  if (!resource) {
1069
1070
  logger$m.info(`${msiName$5}: Unavailable. Multiple scopes are not supported.`);
1070
1071
  return false;
1071
1072
  }
1072
- const result = Boolean(process.env.MSI_ENDPOINT);
1073
+ const env = process.env;
1074
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
1073
1075
  if (!result) {
1074
- logger$m.info(`${msiName$5}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
1076
+ logger$m.info(`${msiName$5}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
1075
1077
  }
1076
1078
  return result;
1077
1079
  },
1078
1080
  async getToken(configuration, getTokenOptions = {}) {
1079
1081
  const { identityClient, scopes, clientId, resourceId } = configuration;
1080
- if (clientId) {
1081
- logger$m.warning(`${msiName$5}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1082
- }
1083
- if (resourceId) {
1084
- logger$m.warning(`${msiName$5}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
1085
- }
1086
- logger$m.info(`${msiName$5}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
1082
+ logger$m.info(`${msiName$5}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
1087
1083
  const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$4(scopes, clientId, resourceId)), {
1088
1084
  // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1089
1085
  allowInsecureConnection: true }));
@@ -1094,159 +1090,16 @@ const cloudShellMsi = {
1094
1090
 
1095
1091
  // Copyright (c) Microsoft Corporation.
1096
1092
  // Licensed under the MIT license.
1097
- const msiName$4 = "ManagedIdentityCredential - IMDS";
1093
+ const msiName$4 = "ManagedIdentityCredential - Azure Arc MSI";
1098
1094
  const logger$l = credentialLogger(msiName$4);
1099
1095
  /**
1100
1096
  * Generates the options used on the request for an access token.
1101
1097
  */
1102
- function prepareRequestOptions$3(scopes, clientId, resourceId, options) {
1103
- var _a;
1098
+ function prepareRequestOptions$3(scopes, clientId, resourceId) {
1104
1099
  const resource = mapScopesToResource(scopes);
1105
1100
  if (!resource) {
1106
1101
  throw new Error(`${msiName$4}: Multiple scopes are not supported.`);
1107
1102
  }
1108
- const { skipQuery, skipMetadataHeader } = options || {};
1109
- let query = "";
1110
- // Pod Identity will try to process this request even if the Metadata header is missing.
1111
- // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
1112
- if (!skipQuery) {
1113
- const queryParameters = {
1114
- resource,
1115
- "api-version": imdsApiVersion,
1116
- };
1117
- if (clientId) {
1118
- queryParameters.client_id = clientId;
1119
- }
1120
- if (resourceId) {
1121
- queryParameters.msi_res_id = resourceId;
1122
- }
1123
- const params = new URLSearchParams(queryParameters);
1124
- query = `?${params.toString()}`;
1125
- }
1126
- const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
1127
- const rawHeaders = {
1128
- Accept: "application/json",
1129
- Metadata: "true",
1130
- };
1131
- // Remove the Metadata header to invoke a request error from some IMDS endpoints.
1132
- if (skipMetadataHeader) {
1133
- delete rawHeaders.Metadata;
1134
- }
1135
- return {
1136
- // In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
1137
- url: `${url}${query}`,
1138
- method: "GET",
1139
- headers: coreRestPipeline.createHttpHeaders(rawHeaders),
1140
- };
1141
- }
1142
- // 800ms -> 1600ms -> 3200ms
1143
- const imdsMsiRetryConfig = {
1144
- maxRetries: 3,
1145
- startDelayInMs: 800,
1146
- intervalIncrement: 2,
1147
- };
1148
- /**
1149
- * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
1150
- */
1151
- const imdsMsi = {
1152
- name: "imdsMsi",
1153
- async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
1154
- const resource = mapScopesToResource(scopes);
1155
- if (!resource) {
1156
- logger$l.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
1157
- return false;
1158
- }
1159
- // if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
1160
- if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1161
- return true;
1162
- }
1163
- if (!identityClient) {
1164
- throw new Error("Missing IdentityClient");
1165
- }
1166
- const requestOptions = prepareRequestOptions$3(resource, clientId, resourceId, {
1167
- skipMetadataHeader: true,
1168
- skipQuery: true,
1169
- });
1170
- return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
1171
- var _a, _b;
1172
- requestOptions.tracingOptions = options.tracingOptions;
1173
- // Create a request with a timeout since we expect that
1174
- // not having a "Metadata" header should cause an error to be
1175
- // returned quickly from the endpoint, proving its availability.
1176
- const request = coreRestPipeline.createPipelineRequest(requestOptions);
1177
- // Default to 1000 if the default of 0 is used.
1178
- // Negative values can still be used to disable the timeout.
1179
- request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
1180
- // This MSI uses the imdsEndpoint to get the token, which only uses http://
1181
- request.allowInsecureConnection = true;
1182
- let response;
1183
- try {
1184
- logger$l.info(`${msiName$4}: Pinging the Azure IMDS endpoint`);
1185
- response = await identityClient.sendRequest(request);
1186
- }
1187
- catch (err) {
1188
- // If the request failed, or Node.js was unable to establish a connection,
1189
- // or the host was down, we'll assume the IMDS endpoint isn't available.
1190
- if (coreUtil.isError(err)) {
1191
- logger$l.verbose(`${msiName$4}: Caught error ${err.name}: ${err.message}`);
1192
- }
1193
- // 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"
1194
- // rather than just timing out, as expected.
1195
- logger$l.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
1196
- return false;
1197
- }
1198
- if (response.status === 403) {
1199
- if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("A socket operation was attempted to an unreachable network")) {
1200
- logger$l.info(`${msiName$4}: The Azure IMDS endpoint is unavailable`);
1201
- logger$l.info(`${msiName$4}: ${response.bodyAsText}`);
1202
- return false;
1203
- }
1204
- }
1205
- // If we received any response, the endpoint is available
1206
- logger$l.info(`${msiName$4}: The Azure IMDS endpoint is available`);
1207
- return true;
1208
- });
1209
- },
1210
- async getToken(configuration, getTokenOptions = {}) {
1211
- const { identityClient, scopes, clientId, resourceId } = configuration;
1212
- if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1213
- logger$l.info(`${msiName$4}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
1214
- }
1215
- else {
1216
- logger$l.info(`${msiName$4}: Using the default Azure IMDS endpoint ${imdsHost}.`);
1217
- }
1218
- let nextDelayInMs = imdsMsiRetryConfig.startDelayInMs;
1219
- for (let retries = 0; retries < imdsMsiRetryConfig.maxRetries; retries++) {
1220
- try {
1221
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
1222
- const tokenResponse = await identityClient.sendTokenRequest(request);
1223
- return (tokenResponse && tokenResponse.accessToken) || null;
1224
- }
1225
- catch (error) {
1226
- if (error.statusCode === 404) {
1227
- await coreUtil.delay(nextDelayInMs);
1228
- nextDelayInMs *= imdsMsiRetryConfig.intervalIncrement;
1229
- continue;
1230
- }
1231
- throw error;
1232
- }
1233
- }
1234
- throw new AuthenticationError(404, `${msiName$4}: Failed to retrieve IMDS token after ${imdsMsiRetryConfig.maxRetries} retries.`);
1235
- },
1236
- };
1237
-
1238
- // Copyright (c) Microsoft Corporation.
1239
- // Licensed under the MIT license.
1240
- const msiName$3 = "ManagedIdentityCredential - Azure Arc MSI";
1241
- const logger$k = credentialLogger(msiName$3);
1242
- /**
1243
- * Generates the options used on the request for an access token.
1244
- */
1245
- function prepareRequestOptions$2(scopes, clientId, resourceId) {
1246
- const resource = mapScopesToResource(scopes);
1247
- if (!resource) {
1248
- throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
1249
- }
1250
1103
  const queryParameters = {
1251
1104
  resource,
1252
1105
  "api-version": azureArcAPIVersion,
@@ -1259,7 +1112,7 @@ function prepareRequestOptions$2(scopes, clientId, resourceId) {
1259
1112
  }
1260
1113
  // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1261
1114
  if (!process.env.IDENTITY_ENDPOINT) {
1262
- throw new Error(`${msiName$3}: Missing environment variable: IDENTITY_ENDPOINT`);
1115
+ throw new Error(`${msiName$4}: Missing environment variable: IDENTITY_ENDPOINT`);
1263
1116
  }
1264
1117
  const query = new URLSearchParams(queryParameters);
1265
1118
  return coreRestPipeline.createPipelineRequest({
@@ -1294,7 +1147,7 @@ async function filePathRequest(identityClient, requestPrepareOptions) {
1294
1147
  if (response.bodyAsText) {
1295
1148
  message = ` Response: ${response.bodyAsText}`;
1296
1149
  }
1297
- throw new AuthenticationError(response.status, `${msiName$3}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
1150
+ throw new AuthenticationError(response.status, `${msiName$4}: To authenticate with Azure Arc MSI, status code 401 is expected on the first request. ${message}`);
1298
1151
  }
1299
1152
  const authHeader = response.headers.get("www-authenticate") || "";
1300
1153
  try {
@@ -1312,12 +1165,12 @@ const arcMsi = {
1312
1165
  async isAvailable({ scopes }) {
1313
1166
  const resource = mapScopesToResource(scopes);
1314
1167
  if (!resource) {
1315
- logger$k.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
1168
+ logger$l.info(`${msiName$4}: Unavailable. Multiple scopes are not supported.`);
1316
1169
  return false;
1317
1170
  }
1318
1171
  const result = Boolean(process.env.IMDS_ENDPOINT && process.env.IDENTITY_ENDPOINT);
1319
1172
  if (!result) {
1320
- logger$k.info(`${msiName$3}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
1173
+ logger$l.info(`${msiName$4}: The environment variables needed are: IMDS_ENDPOINT and IDENTITY_ENDPOINT`);
1321
1174
  }
1322
1175
  return result;
1323
1176
  },
@@ -1325,16 +1178,16 @@ const arcMsi = {
1325
1178
  var _a;
1326
1179
  const { identityClient, scopes, clientId, resourceId } = configuration;
1327
1180
  if (clientId) {
1328
- logger$k.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1181
+ logger$l.warning(`${msiName$4}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1329
1182
  }
1330
1183
  if (resourceId) {
1331
- logger$k.warning(`${msiName$3}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
1184
+ logger$l.warning(`${msiName$4}: user defined managed Identity by resource Id is not supported. Argument resourceId will be ignored.`);
1332
1185
  }
1333
- logger$k.info(`${msiName$3}: Authenticating.`);
1334
- const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), { allowInsecureConnection: true });
1186
+ logger$l.info(`${msiName$4}: Authenticating.`);
1187
+ const requestOptions = Object.assign(Object.assign({ disableJsonStringifyOnBody: true, deserializationMapper: undefined, abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$3(scopes, clientId, resourceId)), { allowInsecureConnection: true });
1335
1188
  const filePath = await filePathRequest(identityClient, requestOptions);
1336
1189
  if (!filePath) {
1337
- throw new Error(`${msiName$3}: Failed to find the token file.`);
1190
+ throw new Error(`${msiName$4}: Failed to find the token file.`);
1338
1191
  }
1339
1192
  const key = await readFileAsync$1(filePath, { encoding: "utf-8" });
1340
1193
  (_a = requestOptions.headers) === null || _a === void 0 ? void 0 : _a.set("Authorization", `Basic ${key}`);
@@ -1346,12 +1199,174 @@ const arcMsi = {
1346
1199
  },
1347
1200
  };
1348
1201
 
1202
+ // Copyright (c) Microsoft Corporation.
1203
+ // Licensed under the MIT license.
1204
+ const msiName$3 = "ManagedIdentityCredential - CloudShellMSI";
1205
+ const logger$k = credentialLogger(msiName$3);
1206
+ /**
1207
+ * Generates the options used on the request for an access token.
1208
+ */
1209
+ function prepareRequestOptions$2(scopes, clientId, resourceId) {
1210
+ const resource = mapScopesToResource(scopes);
1211
+ if (!resource) {
1212
+ throw new Error(`${msiName$3}: Multiple scopes are not supported.`);
1213
+ }
1214
+ const body = {
1215
+ resource,
1216
+ };
1217
+ if (clientId) {
1218
+ body.client_id = clientId;
1219
+ }
1220
+ if (resourceId) {
1221
+ body.msi_res_id = resourceId;
1222
+ }
1223
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1224
+ if (!process.env.MSI_ENDPOINT) {
1225
+ throw new Error(`${msiName$3}: Missing environment variable: MSI_ENDPOINT`);
1226
+ }
1227
+ const params = new URLSearchParams(body);
1228
+ return {
1229
+ url: process.env.MSI_ENDPOINT,
1230
+ method: "POST",
1231
+ body: params.toString(),
1232
+ headers: coreRestPipeline.createHttpHeaders({
1233
+ Accept: "application/json",
1234
+ Metadata: "true",
1235
+ "Content-Type": "application/x-www-form-urlencoded",
1236
+ }),
1237
+ };
1238
+ }
1239
+ /**
1240
+ * Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
1241
+ * 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.
1242
+ */
1243
+ const cloudShellMsi = {
1244
+ name: "cloudShellMsi",
1245
+ async isAvailable({ scopes }) {
1246
+ const resource = mapScopesToResource(scopes);
1247
+ if (!resource) {
1248
+ logger$k.info(`${msiName$3}: Unavailable. Multiple scopes are not supported.`);
1249
+ return false;
1250
+ }
1251
+ const result = Boolean(process.env.MSI_ENDPOINT);
1252
+ if (!result) {
1253
+ logger$k.info(`${msiName$3}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
1254
+ }
1255
+ return result;
1256
+ },
1257
+ async getToken(configuration, getTokenOptions = {}) {
1258
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1259
+ if (clientId) {
1260
+ logger$k.warning(`${msiName$3}: user-assigned identities not supported. The argument clientId might be ignored by the service.`);
1261
+ }
1262
+ if (resourceId) {
1263
+ logger$k.warning(`${msiName$3}: user defined managed Identity by resource Id not supported. The argument resourceId might be ignored by the service.`);
1264
+ }
1265
+ logger$k.info(`${msiName$3}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`);
1266
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$2(scopes, clientId, resourceId)), {
1267
+ // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
1268
+ allowInsecureConnection: true }));
1269
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1270
+ return (tokenResponse && tokenResponse.accessToken) || null;
1271
+ },
1272
+ };
1273
+
1274
+ // Copyright (c) Microsoft Corporation.
1275
+ // Licensed under the MIT license.
1276
+ // This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
1277
+ //
1278
+ // FROM node:12
1279
+ // RUN wget https://host.any/path/bash.sh
1280
+ // CMD ["bash", "bash.sh"]
1281
+ //
1282
+ // Where the bash script contains:
1283
+ //
1284
+ // curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
1285
+ //
1286
+ const msiName$2 = "ManagedIdentityCredential - Fabric MSI";
1287
+ const logger$j = credentialLogger(msiName$2);
1288
+ /**
1289
+ * Generates the options used on the request for an access token.
1290
+ */
1291
+ function prepareRequestOptions$1(scopes, clientId, resourceId) {
1292
+ const resource = mapScopesToResource(scopes);
1293
+ if (!resource) {
1294
+ throw new Error(`${msiName$2}: Multiple scopes are not supported.`);
1295
+ }
1296
+ const queryParameters = {
1297
+ resource,
1298
+ "api-version": azureFabricVersion,
1299
+ };
1300
+ if (clientId) {
1301
+ queryParameters.client_id = clientId;
1302
+ }
1303
+ if (resourceId) {
1304
+ queryParameters.msi_res_id = resourceId;
1305
+ }
1306
+ const query = new URLSearchParams(queryParameters);
1307
+ // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
1308
+ if (!process.env.IDENTITY_ENDPOINT) {
1309
+ throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
1310
+ }
1311
+ if (!process.env.IDENTITY_HEADER) {
1312
+ throw new Error("Missing environment variable: IDENTITY_HEADER");
1313
+ }
1314
+ return {
1315
+ url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
1316
+ method: "GET",
1317
+ headers: coreRestPipeline.createHttpHeaders({
1318
+ Accept: "application/json",
1319
+ secret: process.env.IDENTITY_HEADER,
1320
+ }),
1321
+ };
1322
+ }
1323
+ /**
1324
+ * 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.
1325
+ */
1326
+ const fabricMsi = {
1327
+ name: "fabricMsi",
1328
+ async isAvailable({ scopes }) {
1329
+ const resource = mapScopesToResource(scopes);
1330
+ if (!resource) {
1331
+ logger$j.info(`${msiName$2}: Unavailable. Multiple scopes are not supported.`);
1332
+ return false;
1333
+ }
1334
+ const env = process.env;
1335
+ const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
1336
+ if (!result) {
1337
+ logger$j.info(`${msiName$2}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
1338
+ }
1339
+ return result;
1340
+ },
1341
+ async getToken(configuration, getTokenOptions = {}) {
1342
+ const { scopes, identityClient, clientId, resourceId } = configuration;
1343
+ if (resourceId) {
1344
+ logger$j.warning(`${msiName$2}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
1345
+ }
1346
+ logger$j.info([
1347
+ `${msiName$2}:`,
1348
+ "Using the endpoint and the secret coming from the environment variables:",
1349
+ `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
1350
+ "IDENTITY_HEADER=[REDACTED] and",
1351
+ "IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
1352
+ ].join(" "));
1353
+ const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
1354
+ request.agent = new https.Agent({
1355
+ // This is necessary because Service Fabric provides a self-signed certificate.
1356
+ // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
1357
+ rejectUnauthorized: false,
1358
+ });
1359
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1360
+ return (tokenResponse && tokenResponse.accessToken) || null;
1361
+ },
1362
+ };
1363
+
1349
1364
  // Copyright (c) Microsoft Corporation.
1350
1365
  // Licensed under the MIT license.
1351
1366
  /**
1352
1367
  * @internal
1353
1368
  */
1354
- const logger$j = credentialLogger("IdentityUtils");
1369
+ const logger$i = credentialLogger("IdentityUtils");
1355
1370
  /**
1356
1371
  * Latest AuthenticationRecord version
1357
1372
  * @internal
@@ -1363,7 +1378,7 @@ const LatestAuthenticationRecordVersion = "1.0";
1363
1378
  */
1364
1379
  function ensureValidMsalToken(scopes, msalToken, getTokenOptions) {
1365
1380
  const error = (message) => {
1366
- logger$j.getToken.info(message);
1381
+ logger$i.getToken.info(message);
1367
1382
  return new AuthenticationRequiredError({
1368
1383
  scopes: Array.isArray(scopes) ? scopes : [scopes],
1369
1384
  getTokenOptions,
@@ -1473,17 +1488,17 @@ function handleMsalError(scopes, error, getTokenOptions) {
1473
1488
  const msalError = error;
1474
1489
  switch (msalError.errorCode) {
1475
1490
  case "endpoints_resolution_error":
1476
- logger$j.info(formatError(scopes, error.message));
1491
+ logger$i.info(formatError(scopes, error.message));
1477
1492
  return new CredentialUnavailableError(error.message);
1478
1493
  case "device_code_polling_cancelled":
1479
1494
  return new abortController.AbortError("The authentication has been aborted by the caller.");
1480
1495
  case "consent_required":
1481
1496
  case "interaction_required":
1482
1497
  case "login_required":
1483
- logger$j.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
1498
+ logger$i.info(formatError(scopes, `Authentication returned errorCode ${msalError.errorCode}`));
1484
1499
  break;
1485
1500
  default:
1486
- logger$j.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
1501
+ logger$i.info(formatError(scopes, `Failed to acquire token: ${error.message}`));
1487
1502
  break;
1488
1503
  }
1489
1504
  }
@@ -1493,7 +1508,7 @@ function handleMsalError(scopes, error, getTokenOptions) {
1493
1508
  return error;
1494
1509
  }
1495
1510
  if (error.name === "NativeAuthError") {
1496
- logger$j.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
1511
+ logger$i.info(formatError(scopes, `Error from the native broker: ${error.message} with status code: ${error.statusCode}`));
1497
1512
  return error;
1498
1513
  }
1499
1514
  return new AuthenticationRequiredError({ scopes, getTokenOptions, message: error.message });
@@ -1532,31 +1547,168 @@ function serializeAuthenticationRecord(record) {
1532
1547
  return JSON.stringify(record);
1533
1548
  }
1534
1549
  /**
1535
- * Deserializes a previously serialized authentication record from a string into an object.
1536
- *
1537
- * The input string must contain the following properties:
1538
- *
1539
- * - "authority"
1540
- * - "homeAccountId"
1541
- * - "clientId"
1542
- * - "tenantId"
1543
- * - "username"
1544
- * - "version"
1545
- *
1546
- * If the version we receive is unsupported, an error will be thrown.
1547
- *
1548
- * At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
1549
- *
1550
- * @param serializedRecord - Authentication record previously serialized into string.
1551
- * @returns AuthenticationRecord.
1550
+ * Deserializes a previously serialized authentication record from a string into an object.
1551
+ *
1552
+ * The input string must contain the following properties:
1553
+ *
1554
+ * - "authority"
1555
+ * - "homeAccountId"
1556
+ * - "clientId"
1557
+ * - "tenantId"
1558
+ * - "username"
1559
+ * - "version"
1560
+ *
1561
+ * If the version we receive is unsupported, an error will be thrown.
1562
+ *
1563
+ * At the moment, the only available version is: "1.0", which is always set when the authentication record is serialized.
1564
+ *
1565
+ * @param serializedRecord - Authentication record previously serialized into string.
1566
+ * @returns AuthenticationRecord.
1567
+ */
1568
+ function deserializeAuthenticationRecord(serializedRecord) {
1569
+ const parsed = JSON.parse(serializedRecord);
1570
+ if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
1571
+ throw Error("Unsupported AuthenticationRecord version");
1572
+ }
1573
+ return parsed;
1574
+ }
1575
+
1576
+ // Copyright (c) Microsoft Corporation.
1577
+ // Licensed under the MIT license.
1578
+ const msiName$1 = "ManagedIdentityCredential - IMDS";
1579
+ const logger$h = credentialLogger(msiName$1);
1580
+ /**
1581
+ * Generates the options used on the request for an access token.
1582
+ */
1583
+ function prepareRequestOptions(scopes, clientId, resourceId, options) {
1584
+ var _a;
1585
+ const resource = mapScopesToResource(scopes);
1586
+ if (!resource) {
1587
+ throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
1588
+ }
1589
+ const { skipQuery, skipMetadataHeader } = options || {};
1590
+ let query = "";
1591
+ // Pod Identity will try to process this request even if the Metadata header is missing.
1592
+ // We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
1593
+ if (!skipQuery) {
1594
+ const queryParameters = {
1595
+ resource,
1596
+ "api-version": imdsApiVersion,
1597
+ };
1598
+ if (clientId) {
1599
+ queryParameters.client_id = clientId;
1600
+ }
1601
+ if (resourceId) {
1602
+ queryParameters.msi_res_id = resourceId;
1603
+ }
1604
+ const params = new URLSearchParams(queryParameters);
1605
+ query = `?${params.toString()}`;
1606
+ }
1607
+ const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
1608
+ const rawHeaders = {
1609
+ Accept: "application/json",
1610
+ Metadata: "true",
1611
+ };
1612
+ // Remove the Metadata header to invoke a request error from some IMDS endpoints.
1613
+ if (skipMetadataHeader) {
1614
+ delete rawHeaders.Metadata;
1615
+ }
1616
+ return {
1617
+ // In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
1618
+ url: `${url}${query}`,
1619
+ method: "GET",
1620
+ headers: coreRestPipeline.createHttpHeaders(rawHeaders),
1621
+ };
1622
+ }
1623
+ /**
1624
+ * Defines how to determine whether the Azure IMDS MSI is available, and also how to retrieve a token from the Azure IMDS MSI.
1552
1625
  */
1553
- function deserializeAuthenticationRecord(serializedRecord) {
1554
- const parsed = JSON.parse(serializedRecord);
1555
- if (parsed.version && parsed.version !== LatestAuthenticationRecordVersion) {
1556
- throw Error("Unsupported AuthenticationRecord version");
1557
- }
1558
- return parsed;
1559
- }
1626
+ const imdsMsi = {
1627
+ name: "imdsMsi",
1628
+ async isAvailable({ scopes, identityClient, clientId, resourceId, getTokenOptions = {}, }) {
1629
+ const resource = mapScopesToResource(scopes);
1630
+ if (!resource) {
1631
+ logger$h.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
1632
+ return false;
1633
+ }
1634
+ // if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
1635
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1636
+ return true;
1637
+ }
1638
+ if (!identityClient) {
1639
+ throw new Error("Missing IdentityClient");
1640
+ }
1641
+ const requestOptions = prepareRequestOptions(resource, clientId, resourceId, {
1642
+ skipMetadataHeader: true,
1643
+ skipQuery: true,
1644
+ });
1645
+ return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions, async (options) => {
1646
+ var _a, _b;
1647
+ requestOptions.tracingOptions = options.tracingOptions;
1648
+ // Create a request with a timeout since we expect that
1649
+ // not having a "Metadata" header should cause an error to be
1650
+ // returned quickly from the endpoint, proving its availability.
1651
+ const request = coreRestPipeline.createPipelineRequest(requestOptions);
1652
+ // Default to 1000 if the default of 0 is used.
1653
+ // Negative values can still be used to disable the timeout.
1654
+ request.timeout = ((_a = options.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
1655
+ // This MSI uses the imdsEndpoint to get the token, which only uses http://
1656
+ request.allowInsecureConnection = true;
1657
+ let response;
1658
+ try {
1659
+ logger$h.info(`${msiName$1}: Pinging the Azure IMDS endpoint`);
1660
+ response = await identityClient.sendRequest(request);
1661
+ }
1662
+ catch (err) {
1663
+ // If the request failed, or Node.js was unable to establish a connection,
1664
+ // or the host was down, we'll assume the IMDS endpoint isn't available.
1665
+ if (coreUtil.isError(err)) {
1666
+ logger$h.verbose(`${msiName$1}: Caught error ${err.name}: ${err.message}`);
1667
+ }
1668
+ // 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"
1669
+ // rather than just timing out, as expected.
1670
+ logger$h.info(`${msiName$1}: The Azure IMDS endpoint is unavailable`);
1671
+ return false;
1672
+ }
1673
+ if (response.status === 403) {
1674
+ if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("unreachable")) {
1675
+ logger$h.info(`${msiName$1}: The Azure IMDS endpoint is unavailable`);
1676
+ logger$h.info(`${msiName$1}: ${response.bodyAsText}`);
1677
+ return false;
1678
+ }
1679
+ }
1680
+ // If we received any response, the endpoint is available
1681
+ logger$h.info(`${msiName$1}: The Azure IMDS endpoint is available`);
1682
+ return true;
1683
+ });
1684
+ },
1685
+ async getToken(configuration, getTokenOptions = {}) {
1686
+ const { identityClient, scopes, clientId, resourceId } = configuration;
1687
+ if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
1688
+ logger$h.info(`${msiName$1}: Using the Azure IMDS endpoint coming from the environment variable AZURE_POD_IDENTITY_AUTHORITY_HOST=${process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST}.`);
1689
+ }
1690
+ else {
1691
+ logger$h.info(`${msiName$1}: Using the default Azure IMDS endpoint ${imdsHost}.`);
1692
+ }
1693
+ let nextDelayInMs = configuration.retryConfig.startDelayInMs;
1694
+ for (let retries = 0; retries < configuration.retryConfig.maxRetries; retries++) {
1695
+ try {
1696
+ const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), { allowInsecureConnection: true }));
1697
+ const tokenResponse = await identityClient.sendTokenRequest(request);
1698
+ return (tokenResponse && tokenResponse.accessToken) || null;
1699
+ }
1700
+ catch (error) {
1701
+ if (error.statusCode === 404) {
1702
+ await coreUtil.delay(nextDelayInMs);
1703
+ nextDelayInMs *= configuration.retryConfig.intervalIncrement;
1704
+ continue;
1705
+ }
1706
+ throw error;
1707
+ }
1708
+ }
1709
+ throw new AuthenticationError(404, `${msiName$1}: Failed to retrieve IMDS token after ${configuration.retryConfig.maxRetries} retries.`);
1710
+ },
1711
+ };
1560
1712
 
1561
1713
  // Copyright (c) Microsoft Corporation.
1562
1714
  // Licensed under the MIT license.
@@ -1672,6 +1824,27 @@ var RegionalAuthority;
1672
1824
  /** Uses the {@link RegionalAuthority} for the Azure 'usdodcentral' region. */
1673
1825
  RegionalAuthority["GovernmentUSDodCentral"] = "usdodcentral";
1674
1826
  })(RegionalAuthority || (RegionalAuthority = {}));
1827
+ /**
1828
+ * Calculates the correct regional authority based on the supplied value
1829
+ * and the AZURE_REGIONAL_AUTHORITY_NAME environment variable.
1830
+ *
1831
+ * Values will be returned verbatim, except for {@link RegionalAuthority.AutoDiscoverRegion}
1832
+ * which is mapped to a value MSAL can understand.
1833
+ *
1834
+ * @internal
1835
+ */
1836
+ function calculateRegionalAuthority(regionalAuthority) {
1837
+ var _a, _b;
1838
+ let azureRegion = regionalAuthority;
1839
+ if (azureRegion === undefined &&
1840
+ ((_b = (_a = globalThis.process) === null || _a === void 0 ? void 0 : _a.env) === null || _b === void 0 ? void 0 : _b.AZURE_REGIONAL_AUTHORITY_NAME) !== undefined) {
1841
+ azureRegion = process.env.AZURE_REGIONAL_AUTHORITY_NAME;
1842
+ }
1843
+ if (azureRegion === RegionalAuthority.AutoDiscoverRegion) {
1844
+ return "AUTO_DISCOVER";
1845
+ }
1846
+ return azureRegion;
1847
+ }
1675
1848
 
1676
1849
  // Copyright (c) Microsoft Corporation.
1677
1850
  // Licensed under the MIT license.
@@ -1686,7 +1859,7 @@ var RegionalAuthority;
1686
1859
  */
1687
1860
  class MsalNode {
1688
1861
  constructor(options) {
1689
- var _a, _b, _c, _d, _e, _f, _g;
1862
+ var _a, _b, _c, _d, _e, _f;
1690
1863
  this.app = {};
1691
1864
  this.caeApp = {};
1692
1865
  this.requiresConfidential = false;
@@ -1726,10 +1899,7 @@ class MsalNode {
1726
1899
  "`useIdentityPlugin(createNativeBrokerPlugin())` before using `enableBroker`.",
1727
1900
  ].join(" "));
1728
1901
  }
1729
- this.azureRegion = (_g = options.regionalAuthority) !== null && _g !== void 0 ? _g : process.env.AZURE_REGIONAL_AUTHORITY_NAME;
1730
- if (this.azureRegion === RegionalAuthority.AutoDiscoverRegion) {
1731
- this.azureRegion = "AUTO_DISCOVER";
1732
- }
1902
+ this.azureRegion = calculateRegionalAuthority(options.regionalAuthority);
1733
1903
  }
1734
1904
  /**
1735
1905
  * Generates a MSAL configuration that generally works for Node.js
@@ -2029,7 +2199,7 @@ class MsalClientAssertion extends MsalNode {
2029
2199
 
2030
2200
  // Copyright (c) Microsoft Corporation.
2031
2201
  // Licensed under the MIT license.
2032
- const logger$i = credentialLogger("ClientAssertionCredential");
2202
+ const logger$g = credentialLogger("ClientAssertionCredential");
2033
2203
  /**
2034
2204
  * Authenticates a service principal with a JWT assertion.
2035
2205
  */
@@ -2052,7 +2222,7 @@ class ClientAssertionCredential {
2052
2222
  this.additionallyAllowedTenantIds = resolveAdditionallyAllowedTenantIds(options === null || options === void 0 ? void 0 : options.additionallyAllowedTenants);
2053
2223
  this.clientId = clientId;
2054
2224
  this.options = options;
2055
- this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$i, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
2225
+ this.msalFlow = new MsalClientAssertion(Object.assign(Object.assign({}, options), { logger: logger$g, clientId: this.clientId, tenantId: this.tenantId, tokenCredentialOptions: this.options, getAssertion }));
2056
2226
  }
2057
2227
  /**
2058
2228
  * Authenticates with Microsoft Entra ID and returns an access token if successful.
@@ -2064,7 +2234,7 @@ class ClientAssertionCredential {
2064
2234
  */
2065
2235
  async getToken(scopes, options = {}) {
2066
2236
  return tracingClient.withSpan(`${this.constructor.name}.getToken`, options, async (newOptions) => {
2067
- newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$i);
2237
+ newOptions.tenantId = processMultiTenantRequest(this.tenantId, newOptions, this.additionallyAllowedTenantIds, logger$g);
2068
2238
  const arrayScopes = Array.isArray(scopes) ? scopes : [scopes];
2069
2239
  return this.msalFlow.getToken(arrayScopes, newOptions);
2070
2240
  });
@@ -2086,7 +2256,7 @@ const SupportedWorkloadEnvironmentVariables = [
2086
2256
  "AZURE_CLIENT_ID",
2087
2257
  "AZURE_FEDERATED_TOKEN_FILE",
2088
2258
  ];
2089
- const logger$h = credentialLogger(credentialName$3);
2259
+ const logger$f = credentialLogger(credentialName$3);
2090
2260
  /**
2091
2261
  * Workload Identity authentication is a feature in Azure that allows applications running on virtual machines (VMs)
2092
2262
  * to access other Azure resources without the need for a service principal or managed identity. With Workload Identity
@@ -2112,17 +2282,17 @@ class WorkloadIdentityCredential {
2112
2282
  this.cacheDate = undefined;
2113
2283
  // Logging environment variables for error details
2114
2284
  const assignedEnv = processEnvVars(SupportedWorkloadEnvironmentVariables).assigned.join(", ");
2115
- logger$h.info(`Found the following environment variables: ${assignedEnv}`);
2285
+ logger$f.info(`Found the following environment variables: ${assignedEnv}`);
2116
2286
  const workloadIdentityCredentialOptions = options !== null && options !== void 0 ? options : {};
2117
2287
  const tenantId = workloadIdentityCredentialOptions.tenantId || process.env.AZURE_TENANT_ID;
2118
2288
  const clientId = workloadIdentityCredentialOptions.clientId || process.env.AZURE_CLIENT_ID;
2119
2289
  this.federatedTokenFilePath =
2120
2290
  workloadIdentityCredentialOptions.tokenFilePath || process.env.AZURE_FEDERATED_TOKEN_FILE;
2121
2291
  if (tenantId) {
2122
- checkTenantId(logger$h, tenantId);
2292
+ checkTenantId(logger$f, tenantId);
2123
2293
  }
2124
2294
  if (clientId && tenantId && this.federatedTokenFilePath) {
2125
- logger$h.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
2295
+ logger$f.info(`Invoking ClientAssertionCredential with tenant ID: ${tenantId}, clientId: ${workloadIdentityCredentialOptions.clientId} and federated token path: [REDACTED]`);
2126
2296
  this.client = new ClientAssertionCredential(tenantId, clientId, this.readFileContents.bind(this), options);
2127
2297
  }
2128
2298
  }
@@ -2141,10 +2311,10 @@ class WorkloadIdentityCredential {
2141
2311
  "AZURE_TENANT_ID",
2142
2312
  "AZURE_CLIENT_ID",
2143
2313
  "AZURE_FEDERATED_TOKEN_FILE". See the troubleshooting guide for more information: https://aka.ms/azsdk/js/identity/workloadidentitycredential/troubleshoot `;
2144
- logger$h.info(errorMessage);
2314
+ logger$f.info(errorMessage);
2145
2315
  throw new CredentialUnavailableError(errorMessage);
2146
2316
  }
2147
- logger$h.info("Invoking getToken() of Client Assertion Credential");
2317
+ logger$f.info("Invoking getToken() of Client Assertion Credential");
2148
2318
  return this.client.getToken(scopes, options);
2149
2319
  }
2150
2320
  async readFileContents() {
@@ -2172,8 +2342,8 @@ class WorkloadIdentityCredential {
2172
2342
 
2173
2343
  // Copyright (c) Microsoft Corporation.
2174
2344
  // Licensed under the MIT license.
2175
- const msiName$2 = "ManagedIdentityCredential - Token Exchange";
2176
- const logger$g = credentialLogger(msiName$2);
2345
+ const msiName = "ManagedIdentityCredential - Token Exchange";
2346
+ const logger$e = credentialLogger(msiName);
2177
2347
  /**
2178
2348
  * Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
2179
2349
  */
@@ -2186,7 +2356,7 @@ function tokenExchangeMsi() {
2186
2356
  env.AZURE_TENANT_ID &&
2187
2357
  process.env.AZURE_FEDERATED_TOKEN_FILE);
2188
2358
  if (!result) {
2189
- logger$g.info(`${msiName$2}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
2359
+ logger$e.info(`${msiName}: Unavailable. The environment variables needed are: AZURE_CLIENT_ID (or the client ID sent through the parameters), AZURE_TENANT_ID and AZURE_FEDERATED_TOKEN_FILE`);
2190
2360
  }
2191
2361
  return result;
2192
2362
  },
@@ -2200,164 +2370,6 @@ function tokenExchangeMsi() {
2200
2370
  };
2201
2371
  }
2202
2372
 
2203
- // Copyright (c) Microsoft Corporation.
2204
- // Licensed under the MIT license.
2205
- // This MSI can be easily tested by deploying a container to Azure Service Fabric with the Dockerfile:
2206
- //
2207
- // FROM node:12
2208
- // RUN wget https://host.any/path/bash.sh
2209
- // CMD ["bash", "bash.sh"]
2210
- //
2211
- // Where the bash script contains:
2212
- //
2213
- // curl --insecure $IDENTITY_ENDPOINT'?api-version=2019-07-01-preview&resource=https://vault.azure.net/' -H "Secret: $IDENTITY_HEADER"
2214
- //
2215
- const msiName$1 = "ManagedIdentityCredential - Fabric MSI";
2216
- const logger$f = credentialLogger(msiName$1);
2217
- /**
2218
- * Generates the options used on the request for an access token.
2219
- */
2220
- function prepareRequestOptions$1(scopes, clientId, resourceId) {
2221
- const resource = mapScopesToResource(scopes);
2222
- if (!resource) {
2223
- throw new Error(`${msiName$1}: Multiple scopes are not supported.`);
2224
- }
2225
- const queryParameters = {
2226
- resource,
2227
- "api-version": azureFabricVersion,
2228
- };
2229
- if (clientId) {
2230
- queryParameters.client_id = clientId;
2231
- }
2232
- if (resourceId) {
2233
- queryParameters.msi_res_id = resourceId;
2234
- }
2235
- const query = new URLSearchParams(queryParameters);
2236
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2237
- if (!process.env.IDENTITY_ENDPOINT) {
2238
- throw new Error("Missing environment variable: IDENTITY_ENDPOINT");
2239
- }
2240
- if (!process.env.IDENTITY_HEADER) {
2241
- throw new Error("Missing environment variable: IDENTITY_HEADER");
2242
- }
2243
- return {
2244
- url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
2245
- method: "GET",
2246
- headers: coreRestPipeline.createHttpHeaders({
2247
- Accept: "application/json",
2248
- secret: process.env.IDENTITY_HEADER,
2249
- }),
2250
- };
2251
- }
2252
- /**
2253
- * 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.
2254
- */
2255
- const fabricMsi = {
2256
- name: "fabricMsi",
2257
- async isAvailable({ scopes }) {
2258
- const resource = mapScopesToResource(scopes);
2259
- if (!resource) {
2260
- logger$f.info(`${msiName$1}: Unavailable. Multiple scopes are not supported.`);
2261
- return false;
2262
- }
2263
- const env = process.env;
2264
- const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER && env.IDENTITY_SERVER_THUMBPRINT);
2265
- if (!result) {
2266
- logger$f.info(`${msiName$1}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT, IDENTITY_HEADER and IDENTITY_SERVER_THUMBPRINT`);
2267
- }
2268
- return result;
2269
- },
2270
- async getToken(configuration, getTokenOptions = {}) {
2271
- const { scopes, identityClient, clientId, resourceId } = configuration;
2272
- if (resourceId) {
2273
- logger$f.warning(`${msiName$1}: user defined managed Identity by resource Id is not supported. Argument resourceId might be ignored by the service.`);
2274
- }
2275
- logger$f.info([
2276
- `${msiName$1}:`,
2277
- "Using the endpoint and the secret coming from the environment variables:",
2278
- `IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT},`,
2279
- "IDENTITY_HEADER=[REDACTED] and",
2280
- "IDENTITY_SERVER_THUMBPRINT=[REDACTED].",
2281
- ].join(" "));
2282
- const request = coreRestPipeline.createPipelineRequest(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions$1(scopes, clientId, resourceId)));
2283
- request.agent = new https.Agent({
2284
- // This is necessary because Service Fabric provides a self-signed certificate.
2285
- // The alternative path is to verify the certificate using the IDENTITY_SERVER_THUMBPRINT env variable.
2286
- rejectUnauthorized: false,
2287
- });
2288
- const tokenResponse = await identityClient.sendTokenRequest(request);
2289
- return (tokenResponse && tokenResponse.accessToken) || null;
2290
- },
2291
- };
2292
-
2293
- // Copyright (c) Microsoft Corporation.
2294
- // Licensed under the MIT license.
2295
- const msiName = "ManagedIdentityCredential - AppServiceMSI 2019";
2296
- const logger$e = credentialLogger(msiName);
2297
- /**
2298
- * Generates the options used on the request for an access token.
2299
- */
2300
- function prepareRequestOptions(scopes, clientId, resourceId) {
2301
- const resource = mapScopesToResource(scopes);
2302
- if (!resource) {
2303
- throw new Error(`${msiName}: Multiple scopes are not supported.`);
2304
- }
2305
- const queryParameters = {
2306
- resource,
2307
- "api-version": "2019-08-01",
2308
- };
2309
- if (clientId) {
2310
- queryParameters.client_id = clientId;
2311
- }
2312
- if (resourceId) {
2313
- queryParameters.mi_res_id = resourceId;
2314
- }
2315
- const query = new URLSearchParams(queryParameters);
2316
- // This error should not bubble up, since we verify that this environment variable is defined in the isAvailable() method defined below.
2317
- if (!process.env.IDENTITY_ENDPOINT) {
2318
- throw new Error(`${msiName}: Missing environment variable: IDENTITY_ENDPOINT`);
2319
- }
2320
- if (!process.env.IDENTITY_HEADER) {
2321
- throw new Error(`${msiName}: Missing environment variable: IDENTITY_HEADER`);
2322
- }
2323
- return {
2324
- url: `${process.env.IDENTITY_ENDPOINT}?${query.toString()}`,
2325
- method: "GET",
2326
- headers: coreRestPipeline.createHttpHeaders({
2327
- Accept: "application/json",
2328
- "X-IDENTITY-HEADER": process.env.IDENTITY_HEADER,
2329
- }),
2330
- };
2331
- }
2332
- /**
2333
- * 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.
2334
- */
2335
- const appServiceMsi2019 = {
2336
- name: "appServiceMsi2019",
2337
- async isAvailable({ scopes }) {
2338
- const resource = mapScopesToResource(scopes);
2339
- if (!resource) {
2340
- logger$e.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
2341
- return false;
2342
- }
2343
- const env = process.env;
2344
- const result = Boolean(env.IDENTITY_ENDPOINT && env.IDENTITY_HEADER);
2345
- if (!result) {
2346
- logger$e.info(`${msiName}: Unavailable. The environment variables needed are: IDENTITY_ENDPOINT and IDENTITY_HEADER.`);
2347
- }
2348
- return result;
2349
- },
2350
- async getToken(configuration, getTokenOptions = {}) {
2351
- const { identityClient, scopes, clientId, resourceId } = configuration;
2352
- logger$e.info(`${msiName}: Using the endpoint and the secret coming form the environment variables: IDENTITY_ENDPOINT=${process.env.IDENTITY_ENDPOINT} and IDENTITY_HEADER=[REDACTED].`);
2353
- const request = coreRestPipeline.createPipelineRequest(Object.assign(Object.assign({ abortSignal: getTokenOptions.abortSignal }, prepareRequestOptions(scopes, clientId, resourceId)), {
2354
- // Generally, MSI endpoints use the HTTP protocol, without transport layer security (TLS).
2355
- allowInsecureConnection: true }));
2356
- const tokenResponse = await identityClient.sendTokenRequest(request);
2357
- return (tokenResponse && tokenResponse.accessToken) || null;
2358
- },
2359
- };
2360
-
2361
2373
  // Copyright (c) Microsoft Corporation.
2362
2374
  // Licensed under the MIT license.
2363
2375
  const logger$d = credentialLogger("ManagedIdentityCredential");
@@ -2375,9 +2387,14 @@ class ManagedIdentityCredential {
2375
2387
  * @hidden
2376
2388
  */
2377
2389
  constructor(clientIdOrOptions, options) {
2378
- var _a;
2390
+ var _a, _b;
2379
2391
  this.isEndpointUnavailable = null;
2380
2392
  this.isAppTokenProviderInitialized = false;
2393
+ this.msiRetryConfig = {
2394
+ maxRetries: 3,
2395
+ startDelayInMs: 800,
2396
+ intervalIncrement: 2,
2397
+ };
2381
2398
  let _options;
2382
2399
  if (typeof clientIdOrOptions === "string") {
2383
2400
  this.clientId = clientIdOrOptions;
@@ -2392,6 +2409,9 @@ class ManagedIdentityCredential {
2392
2409
  if (this.clientId && this.resourceId) {
2393
2410
  throw new Error(`${ManagedIdentityCredential.name} - Client Id and Resource Id can't be provided at the same time.`);
2394
2411
  }
2412
+ if (((_a = _options === null || _options === void 0 ? void 0 : _options.retryOptions) === null || _a === void 0 ? void 0 : _a.maxRetries) !== undefined) {
2413
+ this.msiRetryConfig.maxRetries = _options.retryOptions.maxRetries;
2414
+ }
2395
2415
  this.identityClient = new IdentityClient(_options);
2396
2416
  this.isAvailableIdentityClient = new IdentityClient(Object.assign(Object.assign({}, _options), { retryOptions: {
2397
2417
  maxRetries: 0,
@@ -2402,7 +2422,7 @@ class ManagedIdentityCredential {
2402
2422
  this.confidentialApp = new msalCommon.ConfidentialClientApplication({
2403
2423
  auth: {
2404
2424
  authority: "https://login.microsoftonline.com/managed_identity",
2405
- clientId: (_a = this.clientId) !== null && _a !== void 0 ? _a : DeveloperSignOnClientId,
2425
+ clientId: (_b = this.clientId) !== null && _b !== void 0 ? _b : DeveloperSignOnClientId,
2406
2426
  clientSecret: "dummy-secret",
2407
2427
  cloudDiscoveryMetadata: '{"tenant_discovery_endpoint":"https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration","api-version":"1.1","metadata":[{"preferred_network":"login.microsoftonline.com","preferred_cache":"login.windows.net","aliases":["login.microsoftonline.com","login.windows.net","login.microsoft.com","sts.windows.net"]},{"preferred_network":"login.partner.microsoftonline.cn","preferred_cache":"login.partner.microsoftonline.cn","aliases":["login.partner.microsoftonline.cn","login.chinacloudapi.cn"]},{"preferred_network":"login.microsoftonline.de","preferred_cache":"login.microsoftonline.de","aliases":["login.microsoftonline.de"]},{"preferred_network":"login.microsoftonline.us","preferred_cache":"login.microsoftonline.us","aliases":["login.microsoftonline.us","login.usgovcloudapi.net"]},{"preferred_network":"login-us.microsoftonline.com","preferred_cache":"login-us.microsoftonline.com","aliases":["login-us.microsoftonline.com"]}]}',
2408
2428
  authorityMetadata: '{"token_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/token","token_endpoint_auth_methods_supported":["client_secret_post","private_key_jwt","client_secret_basic"],"jwks_uri":"https://login.microsoftonline.com/common/discovery/v2.0/keys","response_modes_supported":["query","fragment","form_post"],"subject_types_supported":["pairwise"],"id_token_signing_alg_values_supported":["RS256"],"response_types_supported":["code","id_token","code id_token","id_token token"],"scopes_supported":["openid","profile","email","offline_access"],"issuer":"https://login.microsoftonline.com/{tenantid}/v2.0","request_uri_parameter_supported":false,"userinfo_endpoint":"https://graph.microsoft.com/oidc/userinfo","authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/authorize","device_authorization_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/devicecode","http_logout_supported":true,"frontchannel_logout_supported":true,"end_session_endpoint":"https://login.microsoftonline.com/common/oauth2/v2.0/logout","claims_supported":["sub","iss","cloud_instance_name","cloud_instance_host_name","cloud_graph_host_name","msgraph_host","aud","exp","iat","auth_time","acr","nonce","preferred_username","name","tid","ver","at_hash","c_hash","email"],"kerberos_endpoint":"https://login.microsoftonline.com/common/kerberos","tenant_region_scope":null,"cloud_instance_name":"microsoftonline.com","cloud_graph_host_name":"graph.windows.net","msgraph_host":"graph.microsoft.com","rbac_url":"https://pas.windows.net"}',
@@ -2452,6 +2472,7 @@ class ManagedIdentityCredential {
2452
2472
  scopes,
2453
2473
  clientId: this.clientId,
2454
2474
  resourceId: this.resourceId,
2475
+ retryConfig: this.msiRetryConfig,
2455
2476
  }, updatedOptions);
2456
2477
  }
2457
2478
  catch (err) {
@@ -2558,10 +2579,10 @@ class ManagedIdentityCredential {
2558
2579
  if (err.statusCode === 400) {
2559
2580
  throw new CredentialUnavailableError(`${ManagedIdentityCredential.name}: The managed identity endpoint is indicating there's no available identity. Message: ${err.message}`);
2560
2581
  }
2561
- // 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"
2582
+ // 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"
2562
2583
  // rather than just timing out, as expected.
2563
2584
  if (err.statusCode === 403 || err.code === 403) {
2564
- if (err.message.includes("A socket operation was attempted to an unreachable network")) {
2585
+ if (err.message.includes("unreachable")) {
2565
2586
  const error = new CredentialUnavailableError(`${ManagedIdentityCredential.name}: Unavailable. Network unreachable. Message: ${err.message}`);
2566
2587
  logger$d.getToken.info(formatError(scopes, error));
2567
2588
  throw error;
@@ -3744,13 +3765,17 @@ const logger$4 = credentialLogger("DefaultAzureCredential");
3744
3765
  *
3745
3766
  * @internal
3746
3767
  */
3747
- function createDefaultManagedIdentityCredential(options) {
3748
- var _a, _b, _c;
3749
- const managedIdentityClientId = (_a = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _a !== void 0 ? _a : process.env.AZURE_CLIENT_ID;
3750
- const workloadIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _b !== void 0 ? _b : managedIdentityClientId;
3768
+ function createDefaultManagedIdentityCredential(options = {}) {
3769
+ var _a, _b, _c, _d;
3770
+ (_a = options.retryOptions) !== null && _a !== void 0 ? _a : (options.retryOptions = {
3771
+ maxRetries: 5,
3772
+ retryDelayInMs: 800,
3773
+ });
3774
+ const managedIdentityClientId = (_b = options === null || options === void 0 ? void 0 : options.managedIdentityClientId) !== null && _b !== void 0 ? _b : process.env.AZURE_CLIENT_ID;
3775
+ const workloadIdentityClientId = (_c = options === null || options === void 0 ? void 0 : options.workloadIdentityClientId) !== null && _c !== void 0 ? _c : managedIdentityClientId;
3751
3776
  const managedResourceId = options === null || options === void 0 ? void 0 : options.managedIdentityResourceId;
3752
3777
  const workloadFile = process.env.AZURE_FEDERATED_TOKEN_FILE;
3753
- const tenantId = (_c = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _c !== void 0 ? _c : process.env.AZURE_TENANT_ID;
3778
+ const tenantId = (_d = options === null || options === void 0 ? void 0 : options.tenantId) !== null && _d !== void 0 ? _d : process.env.AZURE_TENANT_ID;
3754
3779
  if (managedResourceId) {
3755
3780
  const managedIdentityResourceIdOptions = Object.assign(Object.assign({}, options), { resourceId: managedResourceId });
3756
3781
  return new ManagedIdentityCredential(managedIdentityResourceIdOptions);