|
| 1 | +# Managed Identity with MSALJS |
| 2 | + |
| 3 | +### Note |
| 4 | + |
| 5 | +> This feature is in preview and feedback is welcome. See the [preview package](https://www.npmjs.com/package/@azure/msal-node/v/2.6.5-alpha.0) that has been upload to npm. |
| 6 | +
|
| 7 | +A common challenge for developers is the management of secrets, credentials, certificates, and keys used to secure communication between services. [Managed identities](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview) in Azure eliminate the need for developers to handle these credentials manually. MSALJS's msal-node library supports acquiring tokens through the managed identity service when used with applications running inside Azure infrastructure, such as: |
| 8 | + |
| 9 | +- [Azure App Service](https://azure.microsoft.com/products/app-service/) (API version `2019-08-01` and above) |
| 10 | +- [Azure VMs](https://azure.microsoft.com/free/virtual-machines/) |
| 11 | +- [Azure Arc](https://learn.microsoft.com/en-us/azure/azure-arc/overview) |
| 12 | +- [Azure Cloud Shell](https://learn.microsoft.com/en-us/azure/cloud-shell/overview) |
| 13 | +- [Azure Service Fabric](https://learn.microsoft.com/en-us/azure/service-fabric/service-fabric-overview) |
| 14 | + |
| 15 | +For a complete list, refer to [Azure services that can use managed identities to access other services](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/managed-identities-status). |
| 16 | + |
| 17 | +> Browser-based MSALJS libraries do not offer confidential flows because there is no confidentiality between the browser and the token issuer. Additionally, they do not offer managed identity because the browser is not hosted on Azure. |
| 18 | +
|
| 19 | +## Which SDK to use - Azure SDK or MSAL? |
| 20 | + |
| 21 | +MSAL libraries provide lower level APIs that are closer to the OAuth2 and OIDC protocols. |
| 22 | + |
| 23 | +Both MSALJS and [Azure SDK](https://learn.microsoft.com/en-us/javascript/api/overview/azure/identity-readme?view=azure-dotnet&preserve-view=true) allow tokens to be acquired via managed identity. Internally, Azure SDK uses MSALJS, and it provides a higher-level API via its `DefaultAzureCredential` and `ManagedIdentityCredential` abstractions. |
| 24 | + |
| 25 | +If your application already uses one of the SDKs, continue using the same SDK. Use Azure SDK, if you are writing a new application and plan to call other Azure resources, as this SDK provides a better developer experience by allowing the app to run on private developer machines where managed identity doesn't exist. Consider using MSAL if you need to call other downstream web APIs like Microsoft Graph or your own web API. |
| 26 | + |
| 27 | +## Quick start |
| 28 | + |
| 29 | +To quickly get started and see Azure Managed Identity in action, you can use one of [the samples](../../../samples/msal-node-samples/Managed-Identity) the team has built for this purpose. |
| 30 | + |
| 31 | +## How to use managed identities |
| 32 | + |
| 33 | +There are two types of managed identities available to developers - **system-assigned** and **user-assigned**. You can learn more about the differences in the [Managed identity types](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview#managed-identity-types) article. MSALJS supports acquiring tokens with both. [MSALJS logging](https://learn.microsoft.com/en-us/entra/identity-platform/msal-logging-js) allows to keep track of requests and related metadata. |
| 34 | + |
| 35 | +Prior to using managed identities from MSALJS, developers must enable them for the resources they want to use through Azure CLI or the Azure Portal. |
| 36 | + |
| 37 | +## Examples |
| 38 | + |
| 39 | +For both user-assigned and system-assigned identities, developers can use the [ManagedIdentityApplication](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/msi_feature_branch/lib/msal-node/src/client/ManagedIdentityApplication.ts) class. |
| 40 | + |
| 41 | +### System-assigned managed identities |
| 42 | + |
| 43 | +For system-assigned managed identities, the developer does not need to pass any additional information when creating an instance of ManagedIdentityApplication, as it will automatically infer the relevant metadata about the assigned identity. |
| 44 | + |
| 45 | +[acquireToken](https://github.com/AzureAD/microsoft-authentication-library-for-js/blob/msi_feature_branch/lib/msal-node/src/client/ManagedIdentityApplication.ts#L122) is called with the resource to acquire a token for, such as `https://management.azure.com`. |
| 46 | + |
| 47 | +```typescript |
| 48 | +// optional |
| 49 | +const config: ManagedIdentityConfiguration = { |
| 50 | + system: { |
| 51 | + loggerOptions: { |
| 52 | + logLevel: LogLevel.Verbose, |
| 53 | + } as LoggerOptions, |
| 54 | + } as NodeSystemOptions, |
| 55 | +}; |
| 56 | + |
| 57 | +const systemAssignedManagedIdentityApplication: ManagedIdentityApplication = |
| 58 | + new ManagedIdentityApplication(config); |
| 59 | + |
| 60 | +const managedIdentityRequestParams: ManagedIdentityRequestParams = { |
| 61 | + resource: "https://management.azure.com", |
| 62 | +}; |
| 63 | + |
| 64 | +const response: AuthenticationResult = |
| 65 | + await systemAssignedManagedIdentityApplication.acquireToken( |
| 66 | + managedIdentityRequestParams |
| 67 | + ); |
| 68 | +console.log(response); |
| 69 | +``` |
| 70 | + |
| 71 | +### User-assigned managed identities |
| 72 | + |
| 73 | +For user-assigned managed identities, the developer needs to pass either the client ID, full resource identifier, or the object ID of the managed identity when creating ManagedIdentityApplication. |
| 74 | + |
| 75 | +Like in the case for system-assigned managed identities, ` acquireToken` is called with the resource to acquire a token for, such as `https://management.azure.com`. |
| 76 | + |
| 77 | +```typescript |
| 78 | +const managedIdentityIdParams: ManagedIdentityIdParams = { |
| 79 | + userAssignedClientId: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", |
| 80 | +}; |
| 81 | + |
| 82 | +const config: ManagedIdentityConfiguration = { |
| 83 | + managedIdentityIdParams, |
| 84 | + // optional |
| 85 | + system: { |
| 86 | + loggerOptions: { |
| 87 | + logLevel: LogLevel.Verbose, |
| 88 | + } as LoggerOptions, |
| 89 | + } as NodeSystemOptions, |
| 90 | +}; |
| 91 | + |
| 92 | +const userAssignedClientIdManagedIdentityApplication: ManagedIdentityApplication = |
| 93 | + new ManagedIdentityApplication(config); |
| 94 | + |
| 95 | +const managedIdentityRequestParams: ManagedIdentityRequestParams = { |
| 96 | + resource: "https://management.azure.com", |
| 97 | +}; |
| 98 | + |
| 99 | +const response: AuthenticationResult = |
| 100 | + await userAssignedClientIdManagedIdentityApplication.acquireToken( |
| 101 | + managedIdentityRequestParams |
| 102 | + ); |
| 103 | +console.log(response); |
| 104 | +``` |
| 105 | + |
| 106 | +## Caching |
| 107 | + |
| 108 | +MSALJS caches tokens from managed identity in memory. There is no eviction, but memory is not a concern because a limited number of managed identities can be defined. Cache extensibility is not supported in this scenario because tokens should not be shared between machines. |
| 109 | + |
| 110 | +## Troubleshooting |
| 111 | + |
| 112 | +For failed requests the error response contains a correlation ID that can be used for further diagnostics and log analysis. Keep in mind that the correlation IDs generated in MSALJS or passed into MSAL are different than the one returned in server error responses, as MSALJS cannot pass the correlation ID to managed identity token acquisition endpoints. |
| 113 | + |
| 114 | +### Potential errors |
| 115 | + |
| 116 | +#### `ManagedIdentityError` Error Code: `invalid_resource` Error Message: The supplied resource is an invalid URL. |
| 117 | + |
| 118 | +This exception might mean that the resource you are trying to acquire a token for is either not supported or is provided using the wrong resource ID format. Examples of correct resource ID formats include `https://management.azure.com/.default`, `https://management.azure.com`, and `https://graph.microsoft.com`. |
0 commit comments