Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reworked Managed Identity Retry Policy to be per-request #7603

Open
wants to merge 3 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "minor",
"comment": "Reworked Managed Identity Retry Policy to be per-request, which is based on the Managed Identity source. #7603",
"packageName": "@azure/msal-node",
"email": "[email protected]",
"dependentChangeType": "patch"
}
3 changes: 2 additions & 1 deletion lib/msal-node/src/client/ManagedIdentityApplication.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ export class ManagedIdentityApplication {
this.logger,
ManagedIdentityApplication.nodeStorage as NodeStorage,
this.networkClient,
this.cryptoProvider
this.cryptoProvider,
this.config.disableInternalRetries
);
}

Expand Down
24 changes: 20 additions & 4 deletions lib/msal-node/src/client/ManagedIdentityClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export class ManagedIdentityClient {
private nodeStorage: NodeStorage;
private networkClient: INetworkModule;
private cryptoProvider: CryptoProvider;
private disableInternalRetries: boolean;

private static identitySource?: BaseManagedIdentitySource;
public static sourceName?: ManagedIdentitySourceNames;
Expand All @@ -43,12 +44,14 @@ export class ManagedIdentityClient {
logger: Logger,
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean
) {
this.logger = logger;
this.nodeStorage = nodeStorage;
this.networkClient = networkClient;
this.cryptoProvider = cryptoProvider;
this.disableInternalRetries = disableInternalRetries;
}

public async sendManagedIdentityTokenRequest(
Expand All @@ -64,6 +67,7 @@ export class ManagedIdentityClient {
this.nodeStorage,
this.networkClient,
this.cryptoProvider,
this.disableInternalRetries,
managedIdentityId
);
}
Expand Down Expand Up @@ -126,6 +130,7 @@ export class ManagedIdentityClient {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
managedIdentityId: ManagedIdentityId
): BaseManagedIdentitySource {
const source =
Expand All @@ -134,35 +139,46 @@ export class ManagedIdentityClient {
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
managedIdentityId
) ||
AppService.tryCreate(
logger,
nodeStorage,
networkClient,
cryptoProvider
cryptoProvider,
disableInternalRetries
) ||
MachineLearning.tryCreate(
logger,
nodeStorage,
networkClient,
cryptoProvider
cryptoProvider,
disableInternalRetries
) ||
CloudShell.tryCreate(
logger,
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
managedIdentityId
) ||
AzureArc.tryCreate(
logger,
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
managedIdentityId
) ||
Imds.tryCreate(logger, nodeStorage, networkClient, cryptoProvider);
Imds.tryCreate(
logger,
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries
);
if (!source) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.unableToCreateSource
Expand Down
25 changes: 23 additions & 2 deletions lib/msal-node/src/client/ManagedIdentitySources/AppService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ import {
ManagedIdentityEnvironmentVariableNames,
ManagedIdentitySourceNames,
ManagedIdentityIdType,
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON,
} from "../../utils/Constants.js";
import { CryptoProvider } from "../../crypto/CryptoProvider.js";
import { ManagedIdentityRequestParameters } from "../../config/ManagedIdentityRequestParameters.js";
import { ManagedIdentityId } from "../../config/ManagedIdentityId.js";
import { NodeStorage } from "../../cache/NodeStorage.js";
import { LinearRetryPolicy } from "../../retry/LinearRetryPolicy.js";
import { HttpClientWithRetries } from "../../network/HttpClientWithRetries.js";

// MSI Constants. Docs for MSI are available here https://docs.microsoft.com/azure/app-service/overview-managed-identity
const APP_SERVICE_MSI_API_VERSION: string = "2019-08-01";
Expand All @@ -34,10 +39,24 @@ export class AppService extends BaseManagedIdentitySource {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
identityEndpoint: string,
identityHeader: string
) {
super(logger, nodeStorage, networkClient, cryptoProvider);
let networkClientHelper: INetworkModule = networkClient;
if (!disableInternalRetries) {
const linearRetryPolicy: LinearRetryPolicy = new LinearRetryPolicy(
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON
);
networkClientHelper = new HttpClientWithRetries(
networkClient,
linearRetryPolicy
);
}

super(logger, nodeStorage, networkClientHelper, cryptoProvider);

this.identityEndpoint = identityEndpoint;
this.identityHeader = identityHeader;
Expand All @@ -60,7 +79,8 @@ export class AppService extends BaseManagedIdentitySource {
logger: Logger,
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean
): AppService | null {
const [identityEndpoint, identityHeader] =
AppService.getEnvironmentVariables();
Expand Down Expand Up @@ -90,6 +110,7 @@ export class AppService extends BaseManagedIdentitySource {
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
identityEndpoint,
identityHeader
);
Expand Down
23 changes: 22 additions & 1 deletion lib/msal-node/src/client/ManagedIdentitySources/AzureArc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import {
AUTHORIZATION_HEADER_NAME,
AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES,
HttpMethod,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON,
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
METADATA_HEADER_NAME,
ManagedIdentityEnvironmentVariableNames,
ManagedIdentityIdType,
Expand All @@ -42,6 +45,8 @@ import {
import { ManagedIdentityTokenResponse } from "../../response/ManagedIdentityTokenResponse.js";
import { ManagedIdentityId } from "../../config/ManagedIdentityId.js";
import path from "path";
import { LinearRetryPolicy } from "../../retry/LinearRetryPolicy.js";
import { HttpClientWithRetries } from "../../network/HttpClientWithRetries.js";

export const ARC_API_VERSION: string = "2019-11-01";
export const DEFAULT_AZURE_ARC_IDENTITY_ENDPOINT: string =
Expand Down Expand Up @@ -74,9 +79,23 @@ export class AzureArc extends BaseManagedIdentitySource {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
identityEndpoint: string
) {
super(logger, nodeStorage, networkClient, cryptoProvider);
let networkClientHelper: INetworkModule = networkClient;
if (!disableInternalRetries) {
const linearRetryPolicy: LinearRetryPolicy = new LinearRetryPolicy(
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON
);
networkClientHelper = new HttpClientWithRetries(
networkClient,
linearRetryPolicy
);
}

super(logger, nodeStorage, networkClientHelper, cryptoProvider);

this.identityEndpoint = identityEndpoint;
}
Expand Down Expand Up @@ -122,6 +141,7 @@ export class AzureArc extends BaseManagedIdentitySource {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
managedIdentityId: ManagedIdentityId
): AzureArc | null {
const [identityEndpoint, imdsEndpoint] =
Expand Down Expand Up @@ -181,6 +201,7 @@ export class AzureArc extends BaseManagedIdentitySource {
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
identityEndpoint
);
}
Expand Down
23 changes: 22 additions & 1 deletion lib/msal-node/src/client/ManagedIdentitySources/CloudShell.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { NodeStorage } from "../../cache/NodeStorage.js";
import { CryptoProvider } from "../../crypto/CryptoProvider.js";
import {
HttpMethod,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON,
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
METADATA_HEADER_NAME,
ManagedIdentityEnvironmentVariableNames,
ManagedIdentityIdType,
Expand All @@ -21,6 +24,8 @@ import {
createManagedIdentityError,
} from "../../error/ManagedIdentityError.js";
import { ManagedIdentityId } from "../../config/ManagedIdentityId.js";
import { LinearRetryPolicy } from "../../retry/LinearRetryPolicy.js";
import { HttpClientWithRetries } from "../../network/HttpClientWithRetries.js";

/**
* Original source of code: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/CloudShellManagedIdentitySource.cs
Expand All @@ -33,9 +38,23 @@ export class CloudShell extends BaseManagedIdentitySource {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
msiEndpoint: string
) {
super(logger, nodeStorage, networkClient, cryptoProvider);
let networkClientHelper: INetworkModule = networkClient;
if (!disableInternalRetries) {
const linearRetryPolicy: LinearRetryPolicy = new LinearRetryPolicy(
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON
);
networkClientHelper = new HttpClientWithRetries(
networkClient,
linearRetryPolicy
);
}

super(logger, nodeStorage, networkClientHelper, cryptoProvider);

this.msiEndpoint = msiEndpoint;
}
Expand All @@ -52,6 +71,7 @@ export class CloudShell extends BaseManagedIdentitySource {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
managedIdentityId: ManagedIdentityId
): CloudShell | null {
const [msiEndpoint] = CloudShell.getEnvironmentVariables();
Expand Down Expand Up @@ -89,6 +109,7 @@ export class CloudShell extends BaseManagedIdentitySource {
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
msiEndpoint
);
}
Expand Down
25 changes: 23 additions & 2 deletions lib/msal-node/src/client/ManagedIdentitySources/Imds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,18 @@ import { CryptoProvider } from "../../crypto/CryptoProvider.js";
import {
API_VERSION_QUERY_PARAMETER_NAME,
HttpMethod,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON,
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
METADATA_HEADER_NAME,
ManagedIdentityEnvironmentVariableNames,
ManagedIdentityIdType,
ManagedIdentitySourceNames,
RESOURCE_BODY_OR_QUERY_PARAMETER_NAME,
} from "../../utils/Constants.js";
import { NodeStorage } from "../../cache/NodeStorage.js";
import { HttpClientWithRetries } from "../../network/HttpClientWithRetries.js";
import { LinearRetryPolicy } from "../../retry/LinearRetryPolicy.js";

// IMDS constants. Docs for IMDS are available here https://docs.microsoft.com/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
const IMDS_TOKEN_PATH: string = "/metadata/identity/oauth2/token";
Expand All @@ -34,9 +39,23 @@ export class Imds extends BaseManagedIdentitySource {
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean,
identityEndpoint: string
) {
super(logger, nodeStorage, networkClient, cryptoProvider);
let networkClientHelper: INetworkModule = networkClient;
if (!disableInternalRetries) {
const linearRetryPolicy: LinearRetryPolicy = new LinearRetryPolicy(
MANAGED_IDENTITY_MAX_RETRIES,
MANAGED_IDENTITY_RETRY_DELAY,
MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON
);
networkClientHelper = new HttpClientWithRetries(
networkClient,
linearRetryPolicy
);
}

super(logger, nodeStorage, networkClientHelper, cryptoProvider);

this.identityEndpoint = identityEndpoint;
}
Expand All @@ -45,7 +64,8 @@ export class Imds extends BaseManagedIdentitySource {
logger: Logger,
nodeStorage: NodeStorage,
networkClient: INetworkModule,
cryptoProvider: CryptoProvider
cryptoProvider: CryptoProvider,
disableInternalRetries: boolean
): Imds {
let validatedIdentityEndpoint: string;

Expand Down Expand Up @@ -88,6 +108,7 @@ export class Imds extends BaseManagedIdentitySource {
nodeStorage,
networkClient,
cryptoProvider,
disableInternalRetries,
validatedIdentityEndpoint
);
}
Expand Down
Loading