Remove support for customizing the IMDS endpoint within ManagedIdentityCredential using an env var (#5997)

* Remove support for customizing the IMDS endpoint within ManagedIdentityCredential using an env var

* Remove test after merge.

* Revert "Remove test after merge."

This reverts commit 0d1a4fb8ca5c34bc253e999a86d337bbcddea63e.

* Only remove the test, after merge.

* Move imds endpoint url to a named const string and add doc link
This commit is contained in:
Ahson Khan 2024-10-03 13:49:34 -07:00 committed by GitHub
parent 1289063cc2
commit f80caf2fea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 9 additions and 139 deletions

View File

@ -21,6 +21,13 @@ using Azure::Core::_internal::Environment;
using Azure::Identity::_detail::IdentityLog;
namespace {
// https://learn.microsoft.com/azure/virtual-machines/instance-metadata-service
// IMDS is a REST API that's available at a well-known, non-routable IP address (169.254.169.254).
// You can only access it from within the VM. Communication between the VM and IMDS never leaves the
// host.
std::string const ImdsEndpoint = "http://169.254.169.254/metadata/identity/oauth2/token";
std::string WithSourceMessage(std::string const& credSource)
{
return " with " + credSource + " source";
@ -484,29 +491,17 @@ std::unique_ptr<ManagedIdentitySource> ImdsManagedIdentitySource::Create(
credName + " will be created" + WithSourceMessage("Azure Instance Metadata Service")
+ ".\nSuccessful creation does not guarantee further successful token retrieval.");
std::string imdsHost = "http://169.254.169.254";
std::string customImdsHost = Environment::GetVariable("AZURE_IMDS_CUSTOM_AUTHORITY_HOST");
if (!customImdsHost.empty())
{
IdentityLog::Write(
IdentityLog::Level::Informational, "Custom IMDS host is set to: " + customImdsHost);
imdsHost = customImdsHost;
}
Azure::Core::Url imdsUrl(imdsHost);
imdsUrl.AppendPath("/metadata/identity/oauth2/token");
return std::unique_ptr<ManagedIdentitySource>(
new ImdsManagedIdentitySource(clientId, objectId, resourceId, imdsUrl, options));
new ImdsManagedIdentitySource(clientId, objectId, resourceId, options));
}
ImdsManagedIdentitySource::ImdsManagedIdentitySource(
std::string const& clientId,
std::string const& objectId,
std::string const& resourceId,
Azure::Core::Url const& imdsUrl,
Azure::Core::Credentials::TokenCredentialOptions const& options)
: ManagedIdentitySource(clientId, std::string(), options),
m_request(Azure::Core::Http::HttpMethod::Get, imdsUrl)
m_request(Azure::Core::Http::HttpMethod::Get, Azure::Core::Url(ImdsEndpoint))
{
{
using Azure::Core::Url;

View File

@ -197,7 +197,6 @@ namespace Azure { namespace Identity { namespace _detail {
std::string const& clientId,
std::string const& objectId,
std::string const& resourceId,
Core::Url const& imdsUrl,
Core::Credentials::TokenCredentialOptions const& options);
public:

View File

@ -2907,128 +2907,4 @@ namespace Azure { namespace Identity { namespace Test {
EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 3600s);
}
TEST(ManagedIdentityCredential, ImdsCustomHost)
{
auto const actual1 = CredentialTestHelper::SimulateTokenRequest(
[](auto transport) {
TokenCredentialOptions options;
options.Transport.Transport = transport;
CredentialTestHelper::EnvironmentOverride const env({
{"MSI_ENDPOINT", ""},
{"MSI_SECRET", ""},
{"IDENTITY_ENDPOINT", "https://visualstudio.com/"},
{"IMDS_ENDPOINT", ""},
{"IDENTITY_HEADER", ""},
{"IDENTITY_SERVER_THUMBPRINT", ""},
{"AZURE_IMDS_CUSTOM_AUTHORITY_HOST", ""},
});
return std::make_unique<ManagedIdentityCredential>(
"fedcba98-7654-3210-0123-456789abcdef", options);
},
{{"https://azure.com/.default"}},
{"{\"expires_in\":3600, \"access_token\":\"ACCESSTOKEN1\"}"});
auto const actual2 = CredentialTestHelper::SimulateTokenRequest(
[](auto transport) {
TokenCredentialOptions options;
options.Transport.Transport = transport;
CredentialTestHelper::EnvironmentOverride const env({
{"MSI_ENDPOINT", ""},
{"MSI_SECRET", ""},
{"IDENTITY_ENDPOINT", ""},
{"IMDS_ENDPOINT", "https://xbox.com/"},
{"IDENTITY_HEADER", ""},
{"IDENTITY_SERVER_THUMBPRINT", ""},
{"AZURE_IMDS_CUSTOM_AUTHORITY_HOST", "https://custom.imds.endpoint/"},
});
return std::make_unique<ManagedIdentityCredential>(
"01234567-89ab-cdef-fedc-ba9876543210", options);
},
{{"https://outlook.com/.default"}},
{"{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}"});
auto const actual3 = CredentialTestHelper::SimulateTokenRequest(
[](auto transport) {
TokenCredentialOptions options;
options.Transport.Transport = transport;
CredentialTestHelper::EnvironmentOverride const env({
{"MSI_ENDPOINT", ""},
{"MSI_SECRET", ""},
{"IDENTITY_ENDPOINT", ""},
{"IMDS_ENDPOINT", "https://xbox.com/"},
{"IDENTITY_HEADER", ""},
{"IDENTITY_SERVER_THUMBPRINT", ""},
{"AZURE_IMDS_CUSTOM_AUTHORITY_HOST", "http://localhost:59202"},
});
return std::make_unique<ManagedIdentityCredential>(
"01234567-89ab-cdef-fedc-ba9876543210", options);
},
{{"https://outlook.com/.default"}},
{"{\"expires_in\":7200, \"access_token\":\"ACCESSTOKEN2\"}"});
EXPECT_EQ(actual1.Requests.size(), 1U);
EXPECT_EQ(actual1.Responses.size(), 1U);
EXPECT_EQ(actual2.Requests.size(), 1U);
EXPECT_EQ(actual2.Responses.size(), 1U);
auto const& request1 = actual1.Requests.at(0);
auto const& response1 = actual1.Responses.at(0);
auto const& request2 = actual2.Requests.at(0);
auto const& response2 = actual2.Responses.at(0);
EXPECT_EQ(request1.HttpMethod, HttpMethod::Get);
EXPECT_EQ(request2.HttpMethod, HttpMethod::Get);
EXPECT_EQ(
request1.AbsoluteUrl,
"http://169.254.169.254/metadata/identity/oauth2/token"
"?api-version=2018-02-01"
"&client_id=fedcba98-7654-3210-0123-456789abcdef"
"&resource=https%3A%2F%2Fazure.com"); // cspell:disable-line
EXPECT_EQ(
request2.AbsoluteUrl,
"https://custom.imds.endpoint/metadata/identity/oauth2/token"
"?api-version=2018-02-01"
"&client_id=01234567-89ab-cdef-fedc-ba9876543210"
"&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line
auto const& request3 = actual3.Requests.at(0);
EXPECT_EQ(
request3.AbsoluteUrl,
"http://localhost:59202/metadata/identity/oauth2/token"
"?api-version=2018-02-01"
"&client_id=01234567-89ab-cdef-fedc-ba9876543210"
"&resource=https%3A%2F%2Foutlook.com"); // cspell:disable-line
EXPECT_TRUE(request1.Body.empty());
EXPECT_TRUE(request2.Body.empty());
{
EXPECT_NE(request1.Headers.find("Metadata"), request1.Headers.end());
EXPECT_EQ(request1.Headers.at("Metadata"), "true");
EXPECT_NE(request2.Headers.find("Metadata"), request2.Headers.end());
EXPECT_EQ(request2.Headers.at("Metadata"), "true");
}
EXPECT_EQ(response1.AccessToken.Token, "ACCESSTOKEN1");
EXPECT_EQ(response2.AccessToken.Token, "ACCESSTOKEN2");
using namespace std::chrono_literals;
EXPECT_GE(response1.AccessToken.ExpiresOn, response1.EarliestExpiration + 3600s);
EXPECT_LE(response1.AccessToken.ExpiresOn, response1.LatestExpiration + 3600s);
EXPECT_GE(response2.AccessToken.ExpiresOn, response2.EarliestExpiration + 3600s);
EXPECT_LE(response2.AccessToken.ExpiresOn, response2.LatestExpiration + 3600s);
}
}}} // namespace Azure::Identity::Test