Skip to content

Conversation

@Robbie-Microsoft
Copy link
Contributor

Implemented ImdsV2 and ImdsV1 probing

Implements #5594

@Robbie-Microsoft Robbie-Microsoft requested a review from a team as a code owner November 26, 2025 22:42

var queryParams = ImdsQueryParamsHelper(requestContext, apiVersionQueryParam, imdsApiVersion);

var headers = new Dictionary<string, string>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to have some comments here like,

probe deliberately omits the Metadata: true header and then treats 400 as IMDS present

return false;
}

if (response.StatusCode == HttpStatusCode.BadRequest)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’d add a short comment near the StatusCode == BadRequest check explaining why 400 is treated as success, just for future reference.

namespace Microsoft.Identity.Client.Http.Retry
{
internal class CsrMetadataProbeRetryPolicy : ImdsRetryPolicy
internal class ImdsProbeRetryPolicy : ImdsRetryPolicy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider renaming the file to ImdsProbeRetryPolicy.cs

RequestContext requestContext,
bool isMtlsPopRequested)
bool isMtlsPopRequested,
bool noImdsV2 = false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this used anywhere? noImdsV2

ManagedIdentitySource.ImdsV2 => ImdsV2ManagedIdentitySource.Create(requestContext),
_ => new ImdsManagedIdentitySource(requestContext)
ManagedIdentitySource.Imds => ImdsManagedIdentitySource.Create(requestContext),
_ => throw new MsalServiceException(MsalError.ManagedIdentityAllSourcesUnavailable, MsalErrorMessage.ManagedIdentityAllSourcesUnavailable)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this really a service exception?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MsalClientException is more appropriate here.

Assert.ThrowsException<MsalServiceException>(() =>
CsrValidator.ParseRawCsr(badCert));
}
#endregion CSR Generation Tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there tests to validate GetManagedIdentitySourceAsync does not probe again, when the application already returned it as None?

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

namespace Microsoft.Identity.Client.ManagedIdentity.V2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be in Microsoft.Identity.Client.ManagedIdentity namespace?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why @gladjohn ?

}
else
{
requestContext.Logger.Info("[Managed Identity] Mtls Pop was not requested; skipping ImdsV2 probe.");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are really not skipping probe? can we actually do that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what I mean is, "[Managed Identity] Mtls Pop was not requested; skipping ImdsV2 probe." is based on the probe result. Can we actually skip the probe itself?

ManagedIdentityApplication mi = miBuilder.Build() as ManagedIdentityApplication;

Assert.AreEqual(expectedManagedIdentitySource, await mi.GetManagedIdentitySourceAsync().ConfigureAwait(false));
if (managedIdentitySource == ManagedIdentitySource.ImdsV2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a test where we first get a bearer and then request a POP token?


try
{
using (var timeoutCts = new CancellationTokenSource(TimeSpan.FromSeconds(1)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A better pattern for timeout is to let the caller (Azure SDK) provide it, via CancellationToken. So your async method GetSourceAsync() needs to take a parameetr GetSourceAsync(CancellationToken token) and you need to propagate this to the HTTP calls.

Copy link
Member

@bgavrilMS bgavrilMS Dec 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we also want MSAL to provide a default timeout, we can combine our timeout with the one from the caller. But I think we are ok without a timeout of our own? We can always add one later.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants