Skip to content

Commit

Permalink
Implementation Based on Feature Request (#7151)
Browse files Browse the repository at this point in the history
  • Loading branch information
Robbie-Microsoft committed Jun 7, 2024
1 parent cc18b42 commit 3ee9c68
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Implementation Based on Feature Request #7151",
"packageName": "@azure/msal-node",
"email": "rginsburg@microsoft.com",
"dependentChangeType": "patch"
}
63 changes: 60 additions & 3 deletions lib/msal-node/src/client/ManagedIdentitySources/AzureArc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
import {
API_VERSION_QUERY_PARAMETER_NAME,
AUTHORIZATION_HEADER_NAME,
AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES,
HttpMethod,
METADATA_HEADER_NAME,
ManagedIdentityEnvironmentVariableNames,
Expand All @@ -32,12 +33,18 @@ import {
RESOURCE_BODY_OR_QUERY_PARAMETER_NAME,
} from "../../utils/Constants";
import { NodeStorage } from "../../cache/NodeStorage";
import { readFileSync } from "fs";
import { readFileSync, statSync } from "fs";
import { ManagedIdentityTokenResponse } from "../../response/ManagedIdentityTokenResponse";
import { ManagedIdentityId } from "../../config/ManagedIdentityId";
import path from "path";

export const ARC_API_VERSION: string = "2019-11-01";

export const SUPPORTED_AZURE_ARC_PLATFORMS = {
win32: `${process.env["ProgramData"]}\\AzureConnectedMachineAgent\\Tokens\\`,
linux: "/var/opt/azcmagent/tokens/",
};

/**
* Original source of code: https://github.com/Azure/azure-sdk-for-net/blob/main/sdk/identity/Azure.Identity/src/AzureArcManagedIdentitySource.cs
*/
Expand Down Expand Up @@ -168,10 +175,60 @@ export class AzureArc extends BaseManagedIdentitySource {
);
}

const secretFile = wwwAuthHeader.split("Basic realm=")[1];
const secretFilePath = wwwAuthHeader.split("Basic realm=")[1];

// throw an error if the managed identity application is not being run on Windows or Linux
if (
!SUPPORTED_AZURE_ARC_PLATFORMS.hasOwnProperty(process.platform)
) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.platformNotSupported
);
}

// get the expected Windows or Linux file path)
const expectedSecretFilePath: string =
SUPPORTED_AZURE_ARC_PLATFORMS[process.platform as string];

// throw an error if the file in the file path is not a .key file
const fileName: string = path.basename(secretFilePath);
if (!fileName.endsWith(".key")) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.invalidFileExtension
);
}

/*
* throw an error if the file path from the www-authenticate header does not match the
* expected file path for the platform (Windows or Linux) the managed identity application
* is running on
*/
if (expectedSecretFilePath + fileName !== secretFilePath) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.invalidFilePath
);
}

let secretFileSize;
// attempt to get the secret file's size, in bytes
try {
secretFileSize = await statSync(secretFilePath).size;
} catch (e) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.unableToReadSecretFile
);
}
// throw an error if the secret file's size is greater than 4096 bytes
if (secretFileSize > AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.invalidSecret
);
}

// attempt to read the contents of the secret file
let secret;
try {
secret = readFileSync(secretFile, "utf-8");
secret = readFileSync(secretFilePath, "utf-8");
} catch (e) {
throw createManagedIdentityError(
ManagedIdentityErrorCodes.unableToReadSecretFile
Expand Down
8 changes: 8 additions & 0 deletions lib/msal-node/src/error/ManagedIdentityError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,16 @@ export { ManagedIdentityErrorCodes };
* ManagedIdentityErrorMessage class containing string constants used by error codes and messages.
*/
export const ManagedIdentityErrorMessages = {
[ManagedIdentityErrorCodes.invalidFileExtension]:
"The file path in the WWW-Authenticate header does not contain a .key file.",
[ManagedIdentityErrorCodes.invalidFilePath]:
"The file path in the WWW-Authenticate header is not in a valid Windows or Linux Format.",
[ManagedIdentityErrorCodes.invalidManagedIdentityIdType]:
"More than one ManagedIdentityIdType was provided.",
[ManagedIdentityErrorCodes.invalidSecret]:
"The secret in the file on the file path in the WWW-Authenticate header is greater than 4096 bytes.",
[ManagedIdentityErrorCodes.platformNotSupported]:
"The platform is not supported by Azure Arc. Azure Arc only supports Windows and Linux.",
[ManagedIdentityErrorCodes.missingId]:
"A ManagedIdentityId id was not provided.",
[ManagedIdentityErrorCodes.MsiEnvironmentVariableUrlMalformedErrorCodes
Expand Down
4 changes: 4 additions & 0 deletions lib/msal-node/src/error/ManagedIdentityErrorCodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@

import { ManagedIdentityEnvironmentVariableNames } from "../utils/Constants";

export const invalidFileExtension = "invalid_file_extension";
export const invalidFilePath = "invalid_file_path";
export const invalidManagedIdentityIdType = "invalid_managed_identity_id_type";
export const invalidSecret = "invalid_secret";
export const missingId = "missing_client_id";
export const networkUnavailable = "network_unavailable";
export const platformNotSupported = "platform_not_supported";
export const unableToCreateAzureArc = "unable_to_create_azure_arc";
export const unableToCreateCloudShell = "unable_to_create_cloud_shell";
export const unableToCreateSource = "unable_to_create_source";
Expand Down
2 changes: 2 additions & 0 deletions lib/msal-node/src/utils/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ export const LOOPBACK_SERVER_CONSTANTS = {
TIMEOUT_MS: 5000,
};

export const AZURE_ARC_SECRET_FILE_MAX_SIZE_BYTES = 4096; // 4 KB

export const MANAGED_IDENTITY_MAX_RETRIES = 3;
export const MANAGED_IDENTITY_RETRY_DELAY = 1000;
export const MANAGED_IDENTITY_HTTP_STATUS_CODES_TO_RETRY_ON = [
Expand Down
Loading

0 comments on commit 3ee9c68

Please sign in to comment.