Skip to content
Merged
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
14 changes: 14 additions & 0 deletions sdk/identity/identity/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
# Release History

## 2.1.0-beta.1 (Unreleased)

### Features Added

- Added log warning for non-support of user assigned identity in Managed Identity credentials in Cloud Shell environments

### Breaking Changes

### Bugs Fixed

### Other Changes

## 2.0.3 (Unreleased)

### Features Added

- Added log warning for non-support of user assigned identity in Managed Identity credentials in Cloud Shell environments
Comment thread
KarishmaGhiya marked this conversation as resolved.
Outdated

### Breaking Changes

### Bugs Fixed
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { MSI, MSIConfiguration } from "./models";
import { mapScopesToResource } from "./utils";

const msiName = "ManagedIdentityCredential - CloudShellMSI";
const logger = credentialLogger(msiName);
export const logger = credentialLogger(msiName);

/**
* Generates the options used on the request for an access token.
Expand Down Expand Up @@ -53,6 +53,7 @@ function prepareRequestOptions(

/**
* Defines how to determine whether the Azure Cloud Shell MSI is available, and also how to retrieve a token from the Azure Cloud Shell MSI.
* Since Azure Managed Identities aren't available in the Azure Cloud Shell, we log a warning for users that try to access cloud shell using user assigned identity.
Comment thread
sadasant marked this conversation as resolved.
Outdated
*/
export const cloudShellMsi: MSI = {
async isAvailable(scopes): Promise<boolean> {
Expand All @@ -61,6 +62,7 @@ export const cloudShellMsi: MSI = {
logger.info(`${msiName}: Unavailable. Multiple scopes are not supported.`);
return false;
}

const result = Boolean(process.env.MSI_ENDPOINT);
if (!result) {
logger.info(`${msiName}: Unavailable. The environment variable MSI_ENDPOINT is needed.`);
Expand All @@ -73,6 +75,11 @@ export const cloudShellMsi: MSI = {
): Promise<AccessToken | null> {
const { identityClient, scopes, clientId } = configuration;

if (clientId) {
logger.warning(
`${msiName}: does not support user-assigned identities in the Cloud Shell environment. Argument clientId will be ignored.`
);
}
logger.info(
`${msiName}: Using the endpoint coming form the environment variable MSI_ENDPOINT = ${process.env.MSI_ENDPOINT}.`
);
Expand Down
5 changes: 5 additions & 0 deletions sdk/identity/identity/src/util/logging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ export interface CredentialLoggerInstance {
title: string;
fullTitle: string;
info(message: string): void;
warning(message: string): void;
/**
* The logging functions for warning and error are intentionally left out, since we want the identity logging to be at the info level.
* Otherwise, they would look like:
Expand Down Expand Up @@ -97,10 +98,14 @@ export function credentialLoggerInstance(
log.info(`${fullTitle} =>`, message);
}

function warning(message: string): void {
log.warning(`${fullTitle} =>`, message);
}
return {
title,
fullTitle,
info,
warning,
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { tmpdir } from "os";
import { mkdtempSync, rmdirSync, unlinkSync, writeFileSync } from "fs";
import { RestError } from "@azure/core-rest-pipeline";
import { ManagedIdentityCredential } from "../../../src";
import Sinon from "sinon";
import {
imdsHost,
imdsApiVersion,
Expand All @@ -19,6 +20,9 @@ import {
import { createResponse, IdentityTestContextInterface } from "../../httpRequestsCommon";
import { IdentityTestContext } from "../../httpRequests";
import { AzureAuthorityHosts, DefaultAuthorityHost, DefaultTenantId } from "../../../src/constants";
import { setLogLevel } from "@azure/logger";
import { logger } from "../../../src/credentials/managedIdentityCredential/cloudShellMsi";
import { Context } from "mocha";

describe("ManagedIdentityCredential", function () {
let testContext: IdentityTestContextInterface;
Expand Down Expand Up @@ -360,18 +364,35 @@ describe("ManagedIdentityCredential", function () {
it("sends an authorization request correctly in an Cloud Shell environment", async () => {
// Trigger Cloud Shell behavior by setting environment variables
process.env.MSI_ENDPOINT = "https://endpoint";

const authDetails = await testContext.sendCredentialRequests({
scopes: ["https://service/.default"],
credential: new ManagedIdentityCredential("client"),
credential: new ManagedIdentityCredential(),
secureResponses: [createResponse(200, { access_token: "token" })],
});

const authRequest = authDetails.requests[0];
assert.equal(authRequest.method, "POST");
assert.equal(authDetails.result!.token, "token");
});

it("authorization request fails with client id passed in an Cloud Shell environment", async function (this: Context) {
// Trigger Cloud Shell behavior by setting environment variables
process.env.MSI_ENDPOINT = "https://endpoint";
const msiGetTokenSpy = Sinon.spy(ManagedIdentityCredential.prototype, "getToken");
const loggerSpy = Sinon.spy(logger, "warning");
setLogLevel("warning");
const authDetails = await testContext.sendCredentialRequests({
scopes: ["https://service/.default"],
credential: new ManagedIdentityCredential("client"),
secureResponses: [createResponse(200, { access_token: "token" })],
});
assert.equal(authDetails.result!.token, "token");
assert.equal(msiGetTokenSpy.called, true);
assert.equal(loggerSpy.calledOnce, true);
assert.deepEqual(loggerSpy.args[0], [
"ManagedIdentityCredential - CloudShellMSI: does not support user-assigned identities in the Cloud Shell environment. Argument clientId will be ignored.",
]);
});

it("sends an authorization request correctly in an Azure Arc environment", async function (this: Mocha.Context) {
// Trigger Azure Arc behavior by setting environment variables

Expand Down