Initial commit

This commit is contained in:
2025-03-07 19:22:02 +01:00
commit 4a98255d83
55743 changed files with 5280367 additions and 0 deletions
@@ -0,0 +1,18 @@
import type { GetTokenOptions } from "@azure/core-auth";
import type { IdentityClient } from "../../client/identityClient.js";
/**
* Defines how to determine whether the Azure IMDS MSI is available.
*
* Actually getting the token once we determine IMDS is available is handled by MSAL.
*/
export declare const imdsMsi: {
name: string;
isAvailable(options: {
scopes: string | string[];
identityClient?: IdentityClient;
clientId?: string;
resourceId?: string;
getTokenOptions?: GetTokenOptions;
}): Promise<boolean>;
};
//# sourceMappingURL=imdsMsi.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"imdsMsi.d.ts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/imdsMsi.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAIxD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAkErE;;;;GAIG;AACH,eAAO,MAAM,OAAO;;yBAES;QACzB,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;QAC1B,cAAc,CAAC,EAAE,cAAc,CAAC;QAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,eAAe,CAAC,EAAE,eAAe,CAAC;KACnC,GAAG,OAAO,CAAC,OAAO,CAAC;CAmErB,CAAC"}
@@ -0,0 +1,122 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { createHttpHeaders, createPipelineRequest } from "@azure/core-rest-pipeline";
import { isError } from "@azure/core-util";
import { credentialLogger } from "../../util/logging.js";
import { mapScopesToResource } from "./utils.js";
import { tracingClient } from "../../util/tracing.js";
const msiName = "ManagedIdentityCredential - IMDS";
const logger = credentialLogger(msiName);
const imdsHost = "http://169.254.169.254";
const imdsEndpointPath = "/metadata/identity/oauth2/token";
const imdsApiVersion = "2018-02-01";
/**
* Generates the options used on the request for an access token.
*/
function prepareRequestOptions(scopes, clientId, resourceId, options) {
var _a;
const resource = mapScopesToResource(scopes);
if (!resource) {
throw new Error(`${msiName}: Multiple scopes are not supported.`);
}
const { skipQuery, skipMetadataHeader } = options || {};
let query = "";
// Pod Identity will try to process this request even if the Metadata header is missing.
// We can exclude the request query to ensure no IMDS endpoint tries to process the ping request.
if (!skipQuery) {
const queryParameters = {
resource,
"api-version": imdsApiVersion,
};
if (clientId) {
queryParameters.client_id = clientId;
}
if (resourceId) {
queryParameters.msi_res_id = resourceId;
}
const params = new URLSearchParams(queryParameters);
query = `?${params.toString()}`;
}
const url = new URL(imdsEndpointPath, (_a = process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) !== null && _a !== void 0 ? _a : imdsHost);
const rawHeaders = {
Accept: "application/json",
Metadata: "true",
};
// Remove the Metadata header to invoke a request error from some IMDS endpoints.
if (skipMetadataHeader) {
delete rawHeaders.Metadata;
}
return {
// In this case, the `?` should be added in the "query" variable `skipQuery` is not set.
url: `${url}${query}`,
method: "GET",
headers: createHttpHeaders(rawHeaders),
};
}
/**
* Defines how to determine whether the Azure IMDS MSI is available.
*
* Actually getting the token once we determine IMDS is available is handled by MSAL.
*/
export const imdsMsi = {
name: "imdsMsi",
async isAvailable(options) {
const { scopes, identityClient, clientId, resourceId, getTokenOptions } = options;
const resource = mapScopesToResource(scopes);
if (!resource) {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}
// if the PodIdentityEndpoint environment variable was set no need to probe the endpoint, it can be assumed to exist
if (process.env.AZURE_POD_IDENTITY_AUTHORITY_HOST) {
return true;
}
if (!identityClient) {
throw new Error("Missing IdentityClient");
}
const requestOptions = prepareRequestOptions(resource, clientId, resourceId, {
skipMetadataHeader: true,
skipQuery: true,
});
return tracingClient.withSpan("ManagedIdentityCredential-pingImdsEndpoint", getTokenOptions !== null && getTokenOptions !== void 0 ? getTokenOptions : {}, async (updatedOptions) => {
var _a, _b;
requestOptions.tracingOptions = updatedOptions.tracingOptions;
// Create a request with a timeout since we expect that
// not having a "Metadata" header should cause an error to be
// returned quickly from the endpoint, proving its availability.
const request = createPipelineRequest(requestOptions);
// Default to 1000 if the default of 0 is used.
// Negative values can still be used to disable the timeout.
request.timeout = ((_a = updatedOptions.requestOptions) === null || _a === void 0 ? void 0 : _a.timeout) || 1000;
// This MSI uses the imdsEndpoint to get the token, which only uses http://
request.allowInsecureConnection = true;
let response;
try {
logger.info(`${msiName}: Pinging the Azure IMDS endpoint`);
response = await identityClient.sendRequest(request);
}
catch (err) {
// If the request failed, or Node.js was unable to establish a connection,
// or the host was down, we'll assume the IMDS endpoint isn't available.
if (isError(err)) {
logger.verbose(`${msiName}: Caught error ${err.name}: ${err.message}`);
}
// 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"
// rather than just timing out, as expected.
logger.info(`${msiName}: The Azure IMDS endpoint is unavailable`);
return false;
}
if (response.status === 403) {
if ((_b = response.bodyAsText) === null || _b === void 0 ? void 0 : _b.includes("unreachable")) {
logger.info(`${msiName}: The Azure IMDS endpoint is unavailable`);
logger.info(`${msiName}: ${response.bodyAsText}`);
return false;
}
}
// If we received any response, the endpoint is available
logger.info(`${msiName}: The Azure IMDS endpoint is available`);
return true;
});
},
};
//# sourceMappingURL=imdsMsi.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
import type { PipelinePolicy } from "@azure/core-rest-pipeline";
import type { MSIConfiguration } from "./models.js";
/**
* An additional policy that retries on 404 errors. The default retry policy does not retry on
* 404s, but the IMDS endpoint can return 404s when the token is not yet available. This policy
* will retry on 404s with an exponential backoff.
*
* @param msiRetryConfig - The retry configuration for the MSI credential.
* @returns - The policy that will retry on 404s.
*/
export declare function imdsRetryPolicy(msiRetryConfig: MSIConfiguration["retryConfig"]): PipelinePolicy;
//# sourceMappingURL=imdsRetryPolicy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"imdsRetryPolicy.d.ts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/imdsRetryPolicy.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAGhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAMpD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,gBAAgB,CAAC,aAAa,CAAC,GAAG,cAAc,CAqB/F"}
@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { retryPolicy } from "@azure/core-rest-pipeline";
import { calculateRetryDelay } from "@azure/core-util";
// Matches the default retry configuration in expontentialRetryStrategy.ts
const DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;
/**
* An additional policy that retries on 404 errors. The default retry policy does not retry on
* 404s, but the IMDS endpoint can return 404s when the token is not yet available. This policy
* will retry on 404s with an exponential backoff.
*
* @param msiRetryConfig - The retry configuration for the MSI credential.
* @returns - The policy that will retry on 404s.
*/
export function imdsRetryPolicy(msiRetryConfig) {
return retryPolicy([
{
name: "imdsRetryPolicy",
retry: ({ retryCount, response }) => {
if ((response === null || response === void 0 ? void 0 : response.status) !== 404) {
return { skipStrategy: true };
}
return calculateRetryDelay(retryCount, {
retryDelayInMs: msiRetryConfig.startDelayInMs,
maxRetryDelayInMs: DEFAULT_CLIENT_MAX_RETRY_INTERVAL,
});
},
},
], {
maxRetries: msiRetryConfig.maxRetries,
});
}
//# sourceMappingURL=imdsRetryPolicy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"imdsRetryPolicy.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/imdsRetryPolicy.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAGlC,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,iCAAiC,GAAG,IAAI,GAAG,EAAE,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe,CAAC,cAA+C;IAC7E,OAAO,WAAW,CAChB;QACE;YACE,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;gBAClC,IAAI,CAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,MAAK,GAAG,EAAE,CAAC;oBAC7B,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;gBAChC,CAAC;gBAED,OAAO,mBAAmB,CAAC,UAAU,EAAE;oBACrC,cAAc,EAAE,cAAc,CAAC,cAAc;oBAC7C,iBAAiB,EAAE,iCAAiC;iBACrD,CAAC,CAAC;YACL,CAAC;SACF;KACF,EACD;QACE,UAAU,EAAE,cAAc,CAAC,UAAU;KACtC,CACF,CAAC;AACJ,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { PipelinePolicy } from \"@azure/core-rest-pipeline\";\nimport { retryPolicy } from \"@azure/core-rest-pipeline\";\n\nimport type { MSIConfiguration } from \"./models.js\";\nimport { calculateRetryDelay } from \"@azure/core-util\";\n\n// Matches the default retry configuration in expontentialRetryStrategy.ts\nconst DEFAULT_CLIENT_MAX_RETRY_INTERVAL = 1000 * 64;\n\n/**\n * An additional policy that retries on 404 errors. The default retry policy does not retry on\n * 404s, but the IMDS endpoint can return 404s when the token is not yet available. This policy\n * will retry on 404s with an exponential backoff.\n *\n * @param msiRetryConfig - The retry configuration for the MSI credential.\n * @returns - The policy that will retry on 404s.\n */\nexport function imdsRetryPolicy(msiRetryConfig: MSIConfiguration[\"retryConfig\"]): PipelinePolicy {\n return retryPolicy(\n [\n {\n name: \"imdsRetryPolicy\",\n retry: ({ retryCount, response }) => {\n if (response?.status !== 404) {\n return { skipStrategy: true };\n }\n\n return calculateRetryDelay(retryCount, {\n retryDelayInMs: msiRetryConfig.startDelayInMs,\n maxRetryDelayInMs: DEFAULT_CLIENT_MAX_RETRY_INTERVAL,\n });\n },\n },\n ],\n {\n maxRetries: msiRetryConfig.maxRetries,\n },\n );\n}\n"]}
@@ -0,0 +1 @@
{"version":3,"file":"index-browser.d.mts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index-browser.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AASrE,qBAAa,yBAA0B,YAAW,eAAe;;IAMlD,QAAQ,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;CAIrD"}
@@ -0,0 +1 @@
{"version":3,"file":"index-browser.mjs","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/index-browser.mts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEtE,MAAM,wBAAwB,GAAG,IAAI,KAAK,CACxC,4DAA4D,CAC7D,CAAC;AACF,MAAM,MAAM,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAE7D,MAAM,OAAO,yBAAyB;IACpC;QACE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QACvD,MAAM,wBAAwB,CAAC;IACjC,CAAC;IAEM,KAAK,CAAC,QAAQ;QACnB,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,EAAE,wBAAwB,CAAC,CAAC,CAAC;QAChE,MAAM,wBAAwB,CAAC;IACjC,CAAC;CACF","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, TokenCredential } from \"@azure/core-auth\";\n\nimport { credentialLogger, formatError } from \"../../util/logging.js\";\n\nconst BrowserNotSupportedError = new Error(\n \"ManagedIdentityCredential is not supported in the browser.\",\n);\nconst logger = credentialLogger(\"ManagedIdentityCredential\");\n\nexport class ManagedIdentityCredential implements TokenCredential {\n constructor() {\n logger.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n\n public async getToken(): Promise<AccessToken | null> {\n logger.getToken.info(formatError(\"\", BrowserNotSupportedError));\n throw BrowserNotSupportedError;\n }\n}\n"]}
@@ -0,0 +1,6 @@
import type { AccessToken, TokenCredential } from "@azure/core-auth";
export declare class ManagedIdentityCredential implements TokenCredential {
constructor();
getToken(): Promise<AccessToken | null>;
}
//# sourceMappingURL=index-browser.d.mts.map
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { credentialLogger, formatError } from "../../util/logging.js";
const BrowserNotSupportedError = new Error("ManagedIdentityCredential is not supported in the browser.");
const logger = credentialLogger("ManagedIdentityCredential");
export class ManagedIdentityCredential {
constructor() {
logger.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
async getToken() {
logger.getToken.info(formatError("", BrowserNotSupportedError));
throw BrowserNotSupportedError;
}
}
//# sourceMappingURL=index-browser.mjs.map
@@ -0,0 +1,24 @@
import type { AccessToken } from "@azure/core-auth";
import type { IdentityClient } from "../../client/identityClient.js";
/**
* @internal
*/
export interface MSIConfiguration {
retryConfig: {
maxRetries: number;
startDelayInMs: number;
intervalIncrement: number;
};
identityClient: IdentityClient;
scopes: string | string[];
clientId?: string;
resourceId?: string;
}
/**
* @internal
* Represents an access token for {@link ManagedIdentity} for internal usage,
* with an expiration time and the time in which token should refresh.
*/
export declare interface MSIToken extends AccessToken {
}
//# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/models.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAErE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE;QACX,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;KAC3B,CAAC;IACF,cAAc,EAAE,cAAc,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,WAAW,QAAS,SAAQ,WAAW;CAAG"}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export {};
//# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/models.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken } from \"@azure/core-auth\";\n\nimport type { IdentityClient } from \"../../client/identityClient.js\";\n\n/**\n * @internal\n */\nexport interface MSIConfiguration {\n retryConfig: {\n maxRetries: number;\n startDelayInMs: number;\n intervalIncrement: number;\n };\n identityClient: IdentityClient;\n scopes: string | string[];\n clientId?: string;\n resourceId?: string;\n}\n\n/**\n * @internal\n * Represents an access token for {@link ManagedIdentity} for internal usage,\n * with an expiration time and the time in which token should refresh.\n */\nexport declare interface MSIToken extends AccessToken {}\n"]}
@@ -0,0 +1,37 @@
import type { TokenCredentialOptions } from "../../tokenCredentialOptions.js";
/**
* Options to send on the {@link ManagedIdentityCredential} constructor.
* This variation supports `clientId` and not `resourceId`, since only one of both is supported.
*/
export interface ManagedIdentityCredentialClientIdOptions extends TokenCredentialOptions {
/**
* The client ID of the user - assigned identity, or app registration(when working with AKS pod - identity).
*/
clientId?: string;
}
/**
* Options to send on the {@link ManagedIdentityCredential} constructor.
* This variation supports `resourceId` and not `clientId`, since only one of both is supported.
*/
export interface ManagedIdentityCredentialResourceIdOptions extends TokenCredentialOptions {
/**
* Allows specifying a custom resource Id.
* In scenarios such as when user assigned identities are created using an ARM template,
* where the resource Id of the identity is known but the client Id can't be known ahead of time,
* this parameter allows programs to use these user assigned identities
* without having to first determine the client Id of the created identity.
*/
resourceId: string;
}
/**
* Options to send on the {@link ManagedIdentityCredential} constructor.
* This variation supports `objectId` as a constructor argument.
*/
export interface ManagedIdentityCredentialObjectIdOptions extends TokenCredentialOptions {
/**
* Allows specifying the object ID of the underlying service principal used to authenticate a user-assigned managed identity.
* This is an alternative to providing a client ID or resource ID and is not required for system-assigned managed identities.
*/
objectId: string;
}
//# sourceMappingURL=options.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/options.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AAE9E;;;GAGG;AACH,MAAM,WAAW,wCAAyC,SAAQ,sBAAsB;IACtF;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,0CAA2C,SAAQ,sBAAsB;IACxF;;;;;;OAMG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,wCAAyC,SAAQ,sBAAsB;IACtF;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
export {};
//# sourceMappingURL=options.js.map
@@ -0,0 +1 @@
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/options.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { TokenCredentialOptions } from \"../../tokenCredentialOptions.js\";\n\n/**\n * Options to send on the {@link ManagedIdentityCredential} constructor.\n * This variation supports `clientId` and not `resourceId`, since only one of both is supported.\n */\nexport interface ManagedIdentityCredentialClientIdOptions extends TokenCredentialOptions {\n /**\n * The client ID of the user - assigned identity, or app registration(when working with AKS pod - identity).\n */\n clientId?: string;\n}\n\n/**\n * Options to send on the {@link ManagedIdentityCredential} constructor.\n * This variation supports `resourceId` and not `clientId`, since only one of both is supported.\n */\nexport interface ManagedIdentityCredentialResourceIdOptions extends TokenCredentialOptions {\n /**\n * Allows specifying a custom resource Id.\n * In scenarios such as when user assigned identities are created using an ARM template,\n * where the resource Id of the identity is known but the client Id can't be known ahead of time,\n * this parameter allows programs to use these user assigned identities\n * without having to first determine the client Id of the created identity.\n */\n resourceId: string;\n}\n\n/**\n * Options to send on the {@link ManagedIdentityCredential} constructor.\n * This variation supports `objectId` as a constructor argument.\n */\nexport interface ManagedIdentityCredentialObjectIdOptions extends TokenCredentialOptions {\n /**\n * Allows specifying the object ID of the underlying service principal used to authenticate a user-assigned managed identity.\n * This is an alternative to providing a client ID or resource ID and is not required for system-assigned managed identities.\n */\n objectId: string;\n}\n"]}
@@ -0,0 +1,14 @@
import type { AccessToken, GetTokenOptions } from "@azure/core-auth";
import type { MSIConfiguration } from "./models.js";
/**
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
*
* Token exchange MSI (used by AKS) is the only MSI implementation handled entirely by Azure Identity.
* The rest have been migrated to MSAL.
*/
export declare const tokenExchangeMsi: {
name: string;
isAvailable(clientId?: string): Promise<boolean>;
getToken(configuration: MSIConfiguration, getTokenOptions?: GetTokenOptions): Promise<AccessToken | null>;
};
//# sourceMappingURL=tokenExchangeMsi.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"tokenExchangeMsi.d.ts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/tokenExchangeMsi.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAQpD;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB;;2BAEE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;4BAerC,gBAAgB,oBACd,eAAe,GAC/B,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;CAY/B,CAAC"}
@@ -0,0 +1,32 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { WorkloadIdentityCredential } from "../workloadIdentityCredential.js";
import { credentialLogger } from "../../util/logging.js";
const msiName = "ManagedIdentityCredential - Token Exchange";
const logger = credentialLogger(msiName);
/**
* Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.
*
* Token exchange MSI (used by AKS) is the only MSI implementation handled entirely by Azure Identity.
* The rest have been migrated to MSAL.
*/
export const tokenExchangeMsi = {
name: "tokenExchangeMsi",
async isAvailable(clientId) {
const env = process.env;
const result = Boolean((clientId || env.AZURE_CLIENT_ID) &&
env.AZURE_TENANT_ID &&
process.env.AZURE_FEDERATED_TOKEN_FILE);
if (!result) {
logger.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`);
}
return result;
},
async getToken(configuration, getTokenOptions = {}) {
const { scopes, clientId } = configuration;
const identityClientTokenCredentialOptions = {};
const workloadIdentityCredential = new WorkloadIdentityCredential(Object.assign(Object.assign({ clientId, tenantId: process.env.AZURE_TENANT_ID, tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE }, identityClientTokenCredentialOptions), { disableInstanceDiscovery: true }));
return workloadIdentityCredential.getToken(scopes, getTokenOptions);
},
};
//# sourceMappingURL=tokenExchangeMsi.js.map
@@ -0,0 +1 @@
{"version":3,"file":"tokenExchangeMsi.js","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/tokenExchangeMsi.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAIlC,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAGzD,MAAM,OAAO,GAAG,4CAA4C,CAAC;AAC7D,MAAM,MAAM,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,kBAAkB;IACxB,KAAK,CAAC,WAAW,CAAC,QAAiB;QACjC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACxB,MAAM,MAAM,GAAG,OAAO,CACpB,CAAC,QAAQ,IAAI,GAAG,CAAC,eAAe,CAAC;YAC/B,GAAG,CAAC,eAAe;YACnB,OAAO,CAAC,GAAG,CAAC,0BAA0B,CACzC,CAAC;QACF,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,CAAC,IAAI,CACT,GAAG,OAAO,qKAAqK,CAChL,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,KAAK,CAAC,QAAQ,CACZ,aAA+B,EAC/B,kBAAmC,EAAE;QAErC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,aAAa,CAAC;QAC3C,MAAM,oCAAoC,GAAG,EAAE,CAAC;QAChD,MAAM,0BAA0B,GAAG,IAAI,0BAA0B,CAAC,8BAChE,QAAQ,EACR,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,EACrC,aAAa,EAAE,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAClD,oCAAoC,KACvC,wBAAwB,EAAE,IAAI,GACM,CAAC,CAAC;QACxC,OAAO,0BAA0B,CAAC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtE,CAAC;CACF,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\nimport type { AccessToken, GetTokenOptions } from \"@azure/core-auth\";\nimport type { MSIConfiguration } from \"./models.js\";\nimport { WorkloadIdentityCredential } from \"../workloadIdentityCredential.js\";\nimport { credentialLogger } from \"../../util/logging.js\";\nimport type { WorkloadIdentityCredentialOptions } from \"../workloadIdentityCredentialOptions.js\";\n\nconst msiName = \"ManagedIdentityCredential - Token Exchange\";\nconst logger = credentialLogger(msiName);\n\n/**\n * Defines how to determine whether the token exchange MSI is available, and also how to retrieve a token from the token exchange MSI.\n *\n * Token exchange MSI (used by AKS) is the only MSI implementation handled entirely by Azure Identity.\n * The rest have been migrated to MSAL.\n */\nexport const tokenExchangeMsi = {\n name: \"tokenExchangeMsi\",\n async isAvailable(clientId?: string): Promise<boolean> {\n const env = process.env;\n const result = Boolean(\n (clientId || env.AZURE_CLIENT_ID) &&\n env.AZURE_TENANT_ID &&\n process.env.AZURE_FEDERATED_TOKEN_FILE,\n );\n if (!result) {\n logger.info(\n `${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`,\n );\n }\n return result;\n },\n async getToken(\n configuration: MSIConfiguration,\n getTokenOptions: GetTokenOptions = {},\n ): Promise<AccessToken | null> {\n const { scopes, clientId } = configuration;\n const identityClientTokenCredentialOptions = {};\n const workloadIdentityCredential = new WorkloadIdentityCredential({\n clientId,\n tenantId: process.env.AZURE_TENANT_ID,\n tokenFilePath: process.env.AZURE_FEDERATED_TOKEN_FILE,\n ...identityClientTokenCredentialOptions,\n disableInstanceDiscovery: true,\n } as WorkloadIdentityCredentialOptions);\n return workloadIdentityCredential.getToken(scopes, getTokenOptions);\n },\n};\n"]}
@@ -0,0 +1,37 @@
/**
* Error message for Service Fabric Managed Identity environment.
*/
export declare const serviceFabricErrorMessage = "Specifying a `clientId` or `resourceId` is not supported by the Service Fabric managed identity environment. The managed identity configuration is determined by the Service Fabric cluster resource configuration. See https://aka.ms/servicefabricmi for more information";
/**
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
* These are GET requests that require sending a `resource` parameter on the query.
* This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
* Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
*
* For that reason, when we encounter multiple scopes, we return undefined.
* It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).
*/
export declare function mapScopesToResource(scopes: string | string[]): string | undefined;
/**
* Internal type roughly matching the raw responses of the authentication endpoints.
*
* @internal
*/
export interface TokenResponseParsedBody {
access_token?: string;
refresh_token?: string;
expires_in: number;
expires_on?: number | string;
refresh_on?: number | string;
}
/**
* Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
* @param body - A parsed response body from the authentication endpoint.
*/
export declare function parseExpirationTimestamp(body: TokenResponseParsedBody): number;
/**
* Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
* @param body - A parsed response body from the authentication endpoint.
*/
export declare function parseRefreshTimestamp(body: TokenResponseParsedBody): number | undefined;
//# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../../src/credentials/managedIdentityCredential/utils.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,eAAO,MAAM,yBAAyB,gRACyO,CAAC;AAEhR;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAiBjF;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,CAwB9E;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAqBvF"}
@@ -0,0 +1,81 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
const DefaultScopeSuffix = "/.default";
/**
* Error message for Service Fabric Managed Identity environment.
*/
export const serviceFabricErrorMessage = "Specifying a `clientId` or `resourceId` is not supported by the Service Fabric managed identity environment. The managed identity configuration is determined by the Service Fabric cluster resource configuration. See https://aka.ms/servicefabricmi for more information";
/**
* Most MSIs send requests to the IMDS endpoint, or a similar endpoint.
* These are GET requests that require sending a `resource` parameter on the query.
* This resource can be derived from the scopes received through the getToken call, as long as only one scope is received.
* Multiple scopes assume that the resulting token will have access to multiple resources, which won't be the case.
*
* For that reason, when we encounter multiple scopes, we return undefined.
* It's up to the individual MSI implementations to throw the errors (which helps us provide less generic errors).
*/
export function mapScopesToResource(scopes) {
let scope = "";
if (Array.isArray(scopes)) {
if (scopes.length !== 1) {
return;
}
scope = scopes[0];
}
else if (typeof scopes === "string") {
scope = scopes;
}
if (!scope.endsWith(DefaultScopeSuffix)) {
return scope;
}
return scope.substr(0, scope.lastIndexOf(DefaultScopeSuffix));
}
/**
* Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
* @param body - A parsed response body from the authentication endpoint.
*/
export function parseExpirationTimestamp(body) {
if (typeof body.expires_on === "number") {
return body.expires_on * 1000;
}
if (typeof body.expires_on === "string") {
const asNumber = +body.expires_on;
if (!isNaN(asNumber)) {
return asNumber * 1000;
}
const asDate = Date.parse(body.expires_on);
if (!isNaN(asDate)) {
return asDate;
}
}
if (typeof body.expires_in === "number") {
return Date.now() + body.expires_in * 1000;
}
throw new Error(`Failed to parse token expiration from body. expires_in="${body.expires_in}", expires_on="${body.expires_on}"`);
}
/**
* Given a token response, return the expiration timestamp as the number of milliseconds from the Unix epoch.
* @param body - A parsed response body from the authentication endpoint.
*/
export function parseRefreshTimestamp(body) {
if (body.refresh_on) {
if (typeof body.refresh_on === "number") {
return body.refresh_on * 1000;
}
if (typeof body.refresh_on === "string") {
const asNumber = +body.refresh_on;
if (!isNaN(asNumber)) {
return asNumber * 1000;
}
const asDate = Date.parse(body.refresh_on);
if (!isNaN(asDate)) {
return asDate;
}
}
throw new Error(`Failed to parse refresh_on from body. refresh_on="${body.refresh_on}"`);
}
else {
return undefined;
}
}
//# sourceMappingURL=utils.js.map
File diff suppressed because one or more lines are too long