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

[identity] log warning for users trying to access cloud shell using user assigned identity #20226

Merged
merged 15 commits into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from 14 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
KarishmaGhiya marked this conversation as resolved.
Show resolved Hide resolved

### 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.
sadasant marked this conversation as resolved.
Show resolved Hide resolved
*/
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 is not needed and not used.",
KarishmaGhiya marked this conversation as resolved.
Show resolved Hide resolved
]);
});

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