Skip to content

Commit

Permalink
[identity] Throw if user-assigned IDs are used for CloudShell MSI (#3…
Browse files Browse the repository at this point in the history
…0955)

### Packages impacted by this PR

@azure/identity

### Issues associated with this PR

Resolves #30380

### Describe the problem that is addressed by this PR

If the Cloud Shell ManagedIdentitySource is detected via MSAL and a
user-assigned managed identity clientID or resourceID is supplied, the
ManagedIdentityCredential should throw.

The rationale for taking this minor breaking change is that CloudShell
does not support specifying a clientID or ResourceID and the current
behavior of silently falling back to attempting to use a system-assigned
identity could be unexpected.

### Provide a list of related PRs _(if any)_

Azure/azure-sdk-for-cpp#5837
  • Loading branch information
maorleger authored Sep 3, 2024
1 parent c1db23f commit db50236
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
4 changes: 4 additions & 0 deletions sdk/identity/identity/BREAKING_CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Breaking Changes

## 4.5.0

As of `@azure/identity` 4.5.0, providing a user-assigned managed identity ID as a constructor argument will throw an error, indicating to the user that this is an invalid scenario. Previously, the user-provided ID would be silently ignored as CloudShell does not support this.

## 4.1.0

As of `@azure/identity` 4.1.0, the number of IMDS probing retries has been increased to 5 (from 3 initially) to match the [IMDS retry guidance](https://learn.microsoft.com/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#retry-guidance) in the `DefaultAzureCredential` and `ManagedIdentityCredential`. The users should be able to override the behavior, if required, by setting the `options.retryOptions.maxRetries` in the respective credential.
Expand Down
2 changes: 2 additions & 0 deletions sdk/identity/identity/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

### Bugs Fixed

- `ManagedIdentityCredential` now throws an error when attempting to pass a user-assigned Managed Identity in a CloudShell environment instead of silently ignoring it. [#30955](https://github.com/Azure/azure-sdk-for-js/pull/30955)

### Other Changes

## 4.5.0-beta.2 (2024-08-13)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export class MsalMsiProvider {
const providedIds = [this.clientId, this.resourceId, this.objectId].filter(Boolean);
if (providedIds.length > 1) {
throw new Error(
`ManagedIdentityCredential - only one of 'clientId', 'resourceId', or 'objectId' can be provided. Received values: ${JSON.stringify(
`ManagedIdentityCredential: only one of 'clientId', 'resourceId', or 'objectId' can be provided. Received values: ${JSON.stringify(
{ clientId: this.clientId, resourceId: this.resourceId, objectId: this.objectId },
)}`,
);
Expand Down Expand Up @@ -120,6 +120,24 @@ export class MsalMsiProvider {
maxRetries: 0,
},
});

// CloudShell MSI will ignore any user-assigned identity passed as parameters. To avoid confusion, we prevent this from happening as early as possible.
if (this.managedIdentityApp.getManagedIdentitySource() === "CloudShell") {
if (this.clientId || this.resourceId || this.objectId) {
logger.warning(
`CloudShell MSI detected with user-provided IDs - throwing. Received values: ${JSON.stringify(
{
clientId: this.clientId,
resourceId: this.resourceId,
objectId: this.objectId,
},
)}.`,
);
throw new CredentialUnavailableError(
"ManagedIdentityCredential: Specifying a user-assigned managed identity is not supported for CloudShell at runtime. When using Managed Identity in CloudShell, omit the clientId, resourceId, and objectId parameters.",
);
}
}
}

/**
Expand Down Expand Up @@ -196,7 +214,7 @@ export class MsalMsiProvider {

if (!isAvailable) {
throw new CredentialUnavailableError(
`ManagedIdentityCredential: Attempted to use the IMDS endpoint, but it is not available.`,
`Attempted to use the IMDS endpoint, but it is not available.`,
);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,27 @@ describe("ManagedIdentityCredential (MSAL)", function () {
);
});
});

describe("when using CloudShell Managed Identity", function () {
it("throws when user-assigned IDs are provided", function () {
Sinon.stub(ManagedIdentityApplication.prototype, "getManagedIdentitySource").returns(
"CloudShell",
);

assert.throws(
() => new MsalMsiProvider({ clientId: "id" }),
/Specifying a user-assigned managed identity is not supported for CloudShell at runtime/,
);
assert.throws(
() => new MsalMsiProvider({ resourceId: "id" }),
/Specifying a user-assigned managed identity is not supported for CloudShell at runtime/,
);
assert.throws(
() => new MsalMsiProvider({ objectId: "id" }),
/Specifying a user-assigned managed identity is not supported for CloudShell at runtime/,
);
});
});
});

describe("#getToken", function () {
Expand Down

0 comments on commit db50236

Please sign in to comment.