Skip to content

Commit d67d233

Browse files
Merge branch 'dev' into rginsburg/http_client_logs
2 parents a513844 + ed5cadc commit d67d233

File tree

8 files changed

+451
-44
lines changed

8 files changed

+451
-44
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": " Improved Managed Identity JSDocs (#8106)",
4+
"packageName": "@azure/msal-node",
5+
"email": "[email protected]",
6+
"dependentChangeType": "patch"
7+
}

lib/msal-node/src/client/ManagedIdentitySources/AppService.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,29 @@ import { NodeStorage } from "../../cache/NodeStorage.js";
2222
const APP_SERVICE_MSI_API_VERSION: string = "2019-08-01";
2323

2424
/**
25+
* Azure App Service Managed Identity Source implementation.
26+
*
27+
* This class provides managed identity authentication for applications running in Azure App Service.
28+
* It uses the local metadata service endpoint available within App Service environments to obtain
29+
* access tokens without requiring explicit credentials.
30+
*
2531
* Original source of code: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/AppServiceManagedIdentitySource.cs
2632
*/
2733
export class AppService extends BaseManagedIdentitySource {
2834
private identityEndpoint: string;
2935
private identityHeader: string;
3036

37+
/**
38+
* Creates a new instance of the AppService managed identity source.
39+
*
40+
* @param logger - Logger instance for diagnostic output
41+
* @param nodeStorage - Node.js storage implementation for caching
42+
* @param networkClient - Network client for making HTTP requests
43+
* @param cryptoProvider - Cryptographic operations provider
44+
* @param disableInternalRetries - Whether to disable internal retry logic
45+
* @param identityEndpoint - The App Service identity endpoint URL
46+
* @param identityHeader - The secret header value required for authentication
47+
*/
3148
constructor(
3249
logger: Logger,
3350
nodeStorage: NodeStorage,
@@ -49,6 +66,16 @@ export class AppService extends BaseManagedIdentitySource {
4966
this.identityHeader = identityHeader;
5067
}
5168

69+
/**
70+
* Retrieves the required environment variables for App Service managed identity.
71+
*
72+
* App Service managed identity requires two environment variables:
73+
* - IDENTITY_ENDPOINT: The URL of the local metadata service
74+
* - IDENTITY_HEADER: A secret header value for authentication
75+
*
76+
* @returns An array containing [identityEndpoint, identityHeader] values from environment variables.
77+
* Either value may be undefined if the environment variable is not set.
78+
*/
5279
public static getEnvironmentVariables(): Array<string | undefined> {
5380
const identityEndpoint: string | undefined =
5481
process.env[
@@ -62,6 +89,21 @@ export class AppService extends BaseManagedIdentitySource {
6289
return [identityEndpoint, identityHeader];
6390
}
6491

92+
/**
93+
* Attempts to create an AppService managed identity source if the environment supports it.
94+
*
95+
* This method checks for the presence of required environment variables and validates
96+
* the identity endpoint URL. If the environment is not suitable for App Service managed
97+
* identity (missing environment variables or invalid endpoint), it returns null.
98+
*
99+
* @param logger - Logger instance for diagnostic output
100+
* @param nodeStorage - Node.js storage implementation for caching
101+
* @param networkClient - Network client for making HTTP requests
102+
* @param cryptoProvider - Cryptographic operations provider
103+
* @param disableInternalRetries - Whether to disable internal retry logic
104+
*
105+
* @returns A new AppService instance if the environment is suitable, null otherwise
106+
*/
65107
public static tryCreate(
66108
logger: Logger,
67109
nodeStorage: NodeStorage,
@@ -103,6 +145,18 @@ export class AppService extends BaseManagedIdentitySource {
103145
);
104146
}
105147

148+
/**
149+
* Creates a managed identity token request for the App Service environment.
150+
*
151+
* This method constructs an HTTP GET request to the App Service identity endpoint
152+
* with the required headers, query parameters, and managed identity configuration.
153+
* The request includes the secret header for authentication and appropriate API version.
154+
*
155+
* @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default")
156+
* @param managedIdentityId - The managed identity configuration specifying whether to use system-assigned or user-assigned identity
157+
*
158+
* @returns A configured ManagedIdentityRequestParameters object ready for network execution
159+
*/
106160
public createRequest(
107161
resource: string,
108162
managedIdentityId: ManagedIdentityId

lib/msal-node/src/client/ManagedIdentitySources/AzureArc.ts

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,27 @@ export const AZURE_ARC_FILE_DETECTION: FilePathMap = {
6363
};
6464

6565
/**
66+
* Azure Arc managed identity source implementation for acquiring tokens from Azure Arc-enabled servers.
67+
*
68+
* This class provides managed identity authentication for applications running on Azure Arc-enabled servers
69+
* by communicating with the local Hybrid Instance Metadata Service (HIMDS). It supports both environment
70+
* variable-based configuration and automatic detection through the HIMDS executable.
71+
*
6672
* Original source of code: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/AzureArcManagedIdentitySource.cs
6773
*/
6874
export class AzureArc extends BaseManagedIdentitySource {
6975
private identityEndpoint: string;
7076

77+
/**
78+
* Creates a new instance of the AzureArc managed identity source.
79+
*
80+
* @param logger - Logger instance for capturing telemetry and diagnostic information
81+
* @param nodeStorage - Storage implementation for caching tokens and metadata
82+
* @param networkClient - Network client for making HTTP requests to the identity endpoint
83+
* @param cryptoProvider - Cryptographic operations provider for token validation and encryption
84+
* @param disableInternalRetries - Flag to disable automatic retry logic for failed requests
85+
* @param identityEndpoint - The Azure Arc identity endpoint URL for token requests
86+
*/
7187
constructor(
7288
logger: Logger,
7389
nodeStorage: NodeStorage,
@@ -87,6 +103,17 @@ export class AzureArc extends BaseManagedIdentitySource {
87103
this.identityEndpoint = identityEndpoint;
88104
}
89105

106+
/**
107+
* Retrieves and validates Azure Arc environment variables for managed identity configuration.
108+
*
109+
* This method checks for IDENTITY_ENDPOINT and IMDS_ENDPOINT environment variables.
110+
* If either is missing, it attempts to detect the Azure Arc environment by checking for
111+
* the HIMDS executable at platform-specific paths. On successful detection, it returns
112+
* the default identity endpoint and a helper string indicating file-based detection.
113+
*
114+
* @returns An array containing [identityEndpoint, imdsEndpoint] where both values are
115+
* strings if Azure Arc is available, or undefined if not available.
116+
*/
90117
public static getEnvironmentVariables(): Array<string | undefined> {
91118
let identityEndpoint: string | undefined =
92119
process.env[
@@ -123,6 +150,25 @@ export class AzureArc extends BaseManagedIdentitySource {
123150
return [identityEndpoint, imdsEndpoint];
124151
}
125152

153+
/**
154+
* Attempts to create an AzureArc managed identity source instance.
155+
*
156+
* Validates the Azure Arc environment by checking environment variables
157+
* and performing file-based detection. It ensures that only system-assigned managed identities
158+
* are supported for Azure Arc scenarios. The method performs comprehensive validation of
159+
* endpoint URLs and logs detailed information about the detection process.
160+
*
161+
* @param logger - Logger instance for capturing creation and validation steps
162+
* @param nodeStorage - Storage implementation for the managed identity source
163+
* @param networkClient - Network client for HTTP communication
164+
* @param cryptoProvider - Cryptographic operations provider
165+
* @param disableInternalRetries - Whether to disable automatic retry mechanisms
166+
* @param managedIdentityId - The managed identity configuration, must be system-assigned
167+
*
168+
* @returns AzureArc instance if the environment supports Azure Arc managed identity, null otherwise
169+
*
170+
* @throws {ManagedIdentityError} When a user-assigned managed identity is specified (not supported for Azure Arc)
171+
*/
126172
public static tryCreate(
127173
logger: Logger,
128174
nodeStorage: NodeStorage,
@@ -193,6 +239,17 @@ export class AzureArc extends BaseManagedIdentitySource {
193239
);
194240
}
195241

242+
/**
243+
* Creates a properly formatted HTTP request for acquiring tokens from the Azure Arc identity endpoint.
244+
*
245+
* This method constructs a GET request to the Azure Arc HIMDS endpoint with the required metadata header
246+
* and query parameters. The endpoint URL is normalized to use 127.0.0.1 instead of localhost for
247+
* consistency. Additional body parameters are calculated by the base class during token acquisition.
248+
*
249+
* @param resource - The target resource/scope for which to request an access token (e.g., "https://graph.microsoft.com/.default")
250+
*
251+
* @returns A configured ManagedIdentityRequestParameters object ready for network execution
252+
*/
196253
public createRequest(resource: string): ManagedIdentityRequestParameters {
197254
const request: ManagedIdentityRequestParameters =
198255
new ManagedIdentityRequestParameters(
@@ -212,6 +269,30 @@ export class AzureArc extends BaseManagedIdentitySource {
212269
return request;
213270
}
214271

272+
/**
273+
* Processes the server response and handles Azure Arc-specific authentication challenges.
274+
*
275+
* This method implements the Azure Arc authentication flow which may require reading a secret file
276+
* for authorization. When the initial request returns HTTP 401 Unauthorized, it extracts the file
277+
* path from the WWW-Authenticate header, validates the file location and size, reads the secret,
278+
* and retries the request with Basic authentication. The method includes comprehensive security
279+
* validations to prevent path traversal and ensure file integrity.
280+
*
281+
* @param originalResponse - The initial HTTP response from the identity endpoint
282+
* @param networkClient - Network client for making the retry request if needed
283+
* @param networkRequest - The original request parameters (modified with auth header for retry)
284+
* @param networkRequestOptions - Additional options for network requests
285+
*
286+
* @returns A promise that resolves to the server token response with access token and metadata
287+
*
288+
* @throws {ManagedIdentityError} When:
289+
* - WWW-Authenticate header is missing or has unsupported format
290+
* - Platform is not supported (not Windows or Linux)
291+
* - Secret file has invalid extension (not .key)
292+
* - Secret file path doesn't match expected platform path
293+
* - Secret file cannot be read or is too large (>4096 bytes)
294+
* @throws {ClientAuthError} When network errors occur during retry request
295+
*/
215296
public async getServerTokenResponseAsync(
216297
originalResponse: NetworkResponse<ManagedIdentityTokenResponse>,
217298
networkClient: INetworkModule,

lib/msal-node/src/client/ManagedIdentitySources/BaseManagedIdentitySource.ts

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,30 @@ export const ManagedIdentityUserAssignedIdQueryParameterNames = {
5151
export type ManagedIdentityUserAssignedIdQueryParameterNames =
5252
(typeof ManagedIdentityUserAssignedIdQueryParameterNames)[keyof typeof ManagedIdentityUserAssignedIdQueryParameterNames];
5353

54+
/**
55+
* Base class for all Managed Identity sources. Provides common functionality for
56+
* authenticating with Azure Managed Identity endpoints across different Azure services
57+
* including IMDS, App Service, Azure Arc, Service Fabric, Cloud Shell, and Machine Learning.
58+
*
59+
* This abstract class handles token acquisition, response processing, and network communication
60+
* while allowing concrete implementations to define source-specific request creation logic.
61+
*/
5462
export abstract class BaseManagedIdentitySource {
5563
protected logger: Logger;
5664
private nodeStorage: NodeStorage;
5765
private networkClient: INetworkModule;
5866
private cryptoProvider: CryptoProvider;
5967
private disableInternalRetries: boolean;
6068

69+
/**
70+
* Creates an instance of BaseManagedIdentitySource.
71+
*
72+
* @param logger - Logger instance for diagnostic information
73+
* @param nodeStorage - Storage interface for caching tokens
74+
* @param networkClient - Network client for making HTTP requests
75+
* @param cryptoProvider - Cryptographic provider for token operations
76+
* @param disableInternalRetries - Whether to disable automatic retry logic
77+
*/
6178
constructor(
6279
logger: Logger,
6380
nodeStorage: NodeStorage,
@@ -72,11 +89,33 @@ export abstract class BaseManagedIdentitySource {
7289
this.disableInternalRetries = disableInternalRetries;
7390
}
7491

92+
/**
93+
* Creates a managed identity request with source-specific parameters.
94+
* This method must be implemented by concrete managed identity sources to define
95+
* how requests are constructed for their specific endpoint requirements.
96+
*
97+
* @param resource - The Azure resource URI for which the access token is requested (e.g., "https://vault.azure.net/")
98+
* @param managedIdentityId - The managed identity configuration specifying system-assigned or user-assigned identity details
99+
*
100+
* @returns Request parameters configured for the specific managed identity source
101+
*/
75102
abstract createRequest(
76-
request: string,
103+
resource: string,
77104
managedIdentityId: ManagedIdentityId
78105
): ManagedIdentityRequestParameters;
79106

107+
/**
108+
* Processes the network response and converts it to a standardized server token response.
109+
* This async version allows for source-specific response processing logic while maintaining
110+
* backward compatibility with the synchronous version.
111+
*
112+
* @param response - The network response containing the managed identity token
113+
* @param _networkClient - Network client used for the request (unused in base implementation)
114+
* @param _networkRequest - The original network request parameters (unused in base implementation)
115+
* @param _networkRequestOptions - The network request options (unused in base implementation)
116+
*
117+
* @returns Promise resolving to a standardized server authorization token response
118+
*/
80119
public async getServerTokenResponseAsync(
81120
response: NetworkResponse<ManagedIdentityTokenResponse>,
82121
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -89,6 +128,15 @@ export abstract class BaseManagedIdentitySource {
89128
return this.getServerTokenResponse(response);
90129
}
91130

131+
/**
132+
* Converts a managed identity token response to a standardized server authorization token response.
133+
* Handles time format conversion, expiration calculation, and error mapping to ensure
134+
* compatibility with the MSAL response handling pipeline.
135+
*
136+
* @param response - The network response containing the managed identity token
137+
*
138+
* @returns Standardized server authorization token response with normalized fields
139+
*/
92140
public getServerTokenResponse(
93141
response: NetworkResponse<ManagedIdentityTokenResponse>
94142
): ServerAuthorizationTokenResponse {
@@ -138,6 +186,21 @@ export abstract class BaseManagedIdentitySource {
138186
return serverTokenResponse;
139187
}
140188

189+
/**
190+
* Acquires an access token using the managed identity endpoint for the specified resource.
191+
* This is the primary method for token acquisition, handling the complete flow from
192+
* request creation through response processing and token caching.
193+
*
194+
* @param managedIdentityRequest - The managed identity request containing resource and optional parameters
195+
* @param managedIdentityId - The managed identity configuration (system or user-assigned)
196+
* @param fakeAuthority - Authority instance used for token caching (managed identity uses a placeholder authority)
197+
* @param refreshAccessToken - Whether this is a token refresh operation
198+
*
199+
* @returns Promise resolving to an authentication result containing the access token and metadata
200+
*
201+
* @throws {AuthError} When network requests fail or token validation fails
202+
* @throws {ClientAuthError} When network errors occur during the request
203+
*/
141204
public async acquireTokenWithManagedIdentity(
142205
managedIdentityRequest: ManagedIdentityRequest,
143206
managedIdentityId: ManagedIdentityId,
@@ -253,6 +316,19 @@ export abstract class BaseManagedIdentitySource {
253316
);
254317
}
255318

319+
/**
320+
* Determines the appropriate query parameter name for user-assigned managed identity
321+
* based on the identity type, API version, and endpoint characteristics.
322+
* Different Azure services and API versions use different parameter names for the same identity types.
323+
*
324+
* @param managedIdentityIdType - The type of user-assigned managed identity (client ID, object ID, or resource ID)
325+
* @param isImds - Whether the request is being made to the IMDS (Instance Metadata Service) endpoint
326+
* @param usesApi2017 - Whether the endpoint uses the 2017-09-01 API version (affects client ID parameter name)
327+
*
328+
* @returns The correct query parameter name for the specified identity type and endpoint
329+
*
330+
* @throws {ManagedIdentityError} When an invalid managed identity ID type is provided
331+
*/
256332
public getManagedIdentityUserAssignedIdQueryParameterKey(
257333
managedIdentityIdType: ManagedIdentityIdType,
258334
isImds?: boolean,
@@ -290,6 +366,20 @@ export abstract class BaseManagedIdentitySource {
290366
}
291367
}
292368

369+
/**
370+
* Validates and normalizes an environment variable containing a URL string.
371+
* This static utility method ensures that environment variables used for managed identity
372+
* endpoints contain properly formatted URLs and provides informative error messages when validation fails.
373+
*
374+
* @param envVariableStringName - The name of the environment variable being validated (for error reporting)
375+
* @param envVariable - The environment variable value containing the URL string
376+
* @param sourceName - The name of the managed identity source (for error reporting)
377+
* @param logger - Logger instance for diagnostic information
378+
*
379+
* @returns The validated and normalized URL string
380+
*
381+
* @throws {ManagedIdentityError} When the environment variable contains a malformed URL
382+
*/
293383
public static getValidatedEnvVariableUrlString = (
294384
envVariableStringName: keyof typeof ManagedIdentityErrorCodes.MsiEnvironmentVariableUrlMalformedErrorCodes,
295385
envVariable: string,

0 commit comments

Comments
 (0)