@@ -34,14 +34,45 @@ using namespace std::chrono;
3434
3535bool areManagedIdentitiesEnabled ()
3636{
37- // Check for Azure AD Workload Identity or legacy managed identity
38- static bool hasWorkloadIdentity = std::getenv (" AZURE_CLIENT_ID" ) &&
39- std::getenv (" AZURE_TENANT_ID" ) &&
40- std::getenv (" AZURE_FEDERATED_TOKEN_FILE" );
41-
42- static bool hasManagedIdentity = std::getenv (" MSI_ENDPOINT" ) || std::getenv (" IDENTITY_ENDPOINT" );
37+ static bool hasIMDS = []() {
38+ // Check for Azure AD Workload Identity or legacy managed identity
39+ if (std::getenv (" AZURE_CLIENT_ID" ) && std::getenv (" AZURE_TENANT_ID" ) && std::getenv (" AZURE_FEDERATED_TOKEN_FILE" ))
40+ return true ;
41+
42+ // Check for App Service / Container Instances managed identity
43+ if (std::getenv (" MSI_ENDPOINT" ) || std::getenv (" IDENTITY_ENDPOINT" ))
44+ return true ;
45+
46+ // Check for Azure VM managed identity via IMDS (Instance Metadata Service) probe (once).
47+ // 169.254.169.254 is a non-routable link-local address that Azure uses to expose the
48+ // IMDS to VMs running on its platform. It is only reachable from within an Azure VM.
49+ // See: https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token#get-a-token-using-http
50+ try
51+ {
52+ Azure::Core::Http::Request request (Azure::Core::Http::HttpMethod::Get, Azure::Core::Url (" http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/" ));
53+ request.SetHeader (" Metadata" , " true" );
54+
55+ auto transport = std::make_shared<Azure::Core::Http::CurlTransport>();
56+ Azure::Core::Context context;
57+ // Use a short timeout to avoid blocking startup if not on Azure
58+ context = context.WithDeadline (std::chrono::system_clock::now () + std::chrono::seconds (2 ));
59+
60+ auto response = transport->Send (request, context);
61+ auto statusCode = response->GetStatusCode ();
62+ // 200 = identity assigned and working
63+ // 400 = IMDS reachable but identity may not be properly configured
64+ if (statusCode == Azure::Core::Http::HttpStatusCode::BadRequest)
65+ OWARNLOG (" Azure IMDS probe returned 400 (Bad Request) — managed identity endpoint is reachable but may not be properly configured" );
66+ return statusCode == Azure::Core::Http::HttpStatusCode::Ok;
67+ }
68+ catch (...)
69+ {
70+ // Connection refused, timeout, not on Azure — IMDS not available
71+ return false ;
72+ }
73+ }();
4374
44- return hasWorkloadIdentity || hasManagedIdentity ;
75+ return hasIMDS ;
4576}
4677
4778std::shared_ptr<Azure::Storage::StorageSharedKeyCredential> getAzureSharedKeyCredential (const char * accountName, const char * secretName)
0 commit comments