From db749c51abd6918fab4a240ac79027388655004a Mon Sep 17 00:00:00 2001 From: g2vinay Date: Mon, 9 Mar 2026 21:55:38 -0700 Subject: [PATCH 1/4] refactor(auth): replace direct Environment.GetEnvironmentVariable calls with IConfiguration All direct Environment.GetEnvironmentVariable calls in the Remote Azure MCP Server auth and startup paths are replaced with IConfiguration-based retrieval, since the configuration system already handles environment variables and other sources (appsettings.json, etc.). Changes: - CustomChainedCredential: add static Configuration property (mirrors the existing CloudConfiguration pattern) and GetConfigValue helper that prefers IConfiguration when set and falls back to env vars for backward compatibility. All env var reads in CreateCredential, CreateBrowserCredential, CreateDefaultCredential, AddManagedIdentityCredential, and ShouldUseOnlyBrokerCredential now use GetConfigValue. - AuthenticationServiceCollectionExtensions: wire the IConfiguration singleton (if registered) into CustomChainedCredential.Configuration when building the single-identity token credential provider. - ServiceStartCommand (HTTP paths): use builder/app IConfiguration instead of Environment.GetEnvironmentVariable for ASPNETCORE_URLS, ALLOW_INSECURE_EXTERNAL_BINDING, AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS, AZURE_MCP_DANGEROUSLY_DISABLE_HTTPS_REDIRECTION, AZURE_MCP_COLLECT_TELEMETRY, and APPLICATIONINSIGHTS_CONNECTION_STRING. AddIncomingAndOutgoingHttpSpans now receives an IConfiguration instance built from env vars before the host is constructed. --- .../Server/Commands/ServiceStartCommand.cs | 40 +++++++++---------- ...thenticationServiceCollectionExtensions.cs | 3 ++ .../Authentication/CustomChainedCredential.cs | 34 +++++++++++----- 3 files changed, 48 insertions(+), 29 deletions(-) diff --git a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs index fe8b56a51a..ca58cedbaf 100644 --- a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs +++ b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs @@ -198,7 +198,13 @@ public override async Task ExecuteAsync(CommandContext context, try { - using var tracerProvider = AddIncomingAndOutgoingHttpSpans(options); + // Build configuration from environment variables so AddIncomingAndOutgoingHttpSpans + // has access to IConfiguration before the host DI container is constructed. + IConfiguration preHostConfiguration = new ConfigurationBuilder() + .AddEnvironmentVariables() + .Build(); + + using var tracerProvider = AddIncomingAndOutgoingHttpSpans(options, preHostConfiguration); using var host = CreateHost(options); @@ -458,14 +464,10 @@ private IHost CreateHttpHost(ServiceStartOptions serverOptions) { WebApplicationBuilder builder = WebApplication.CreateBuilder(HttpWebApplicationOptions); - // Read once at host setup time — this env var is process-wide and effectively static, + // Read once at host setup time — this value is process-wide and effectively static, // so there is no need to re-read it on every incoming request. - // Default to false; the env var must be present and parse to "true" to enable. - bool enableForwardedHeaders = - bool.TryParse( - Environment.GetEnvironmentVariable("AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS"), - out bool parsedEnvVar) - && parsedEnvVar; + // Default to false; the configuration value must parse to "true" to enable. + bool enableForwardedHeaders = builder.Configuration.GetValue("AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS"); // Configure logging builder.Logging.ClearProviders(); @@ -805,7 +807,7 @@ private static void InitializeListingUrls(WebApplicationBuilder builder, Service return; } - string url = Environment.GetEnvironmentVariable("ASPNETCORE_URLS") ?? "http://127.0.0.1:5001"; + string url = builder.Configuration["ASPNETCORE_URLS"] ?? "http://127.0.0.1:5001"; if (url.Contains(';')) { @@ -834,7 +836,7 @@ private static void InitializeListingUrls(WebApplicationBuilder builder, Service throw new InvalidOperationException($"Explicit external binding is not supported for '{url}'."); } - if (isWildcard && !EnvironmentHelpers.GetEnvironmentVariableAsBool("ALLOW_INSECURE_EXTERNAL_BINDING")) + if (isWildcard && !builder.Configuration.GetValue("ALLOW_INSECURE_EXTERNAL_BINDING")) { throw new InvalidOperationException( $"External binding blocked for '{url}'. " + @@ -902,8 +904,7 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) // - The application or server's HTTP stack is not listening for non-HTTPS requests. // // Safe default to enable HTTPS redirection unless explicitly opted-out. - string? httpsRedirectionOptOut = Environment.GetEnvironmentVariable("AZURE_MCP_DANGEROUSLY_DISABLE_HTTPS_REDIRECTION"); - if (!bool.TryParse(httpsRedirectionOptOut, out bool isOptedOut) || !isOptedOut) + if (!app.Configuration.GetValue("AZURE_MCP_DANGEROUSLY_DISABLE_HTTPS_REDIRECTION")) { app.UseHttpsRedirection(); } @@ -915,6 +916,7 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) /// Configures incoming and outgoing HTTP spans for self-hosted HTTP mode with Azure Monitor exporter. /// /// The server configuration options. + /// The configuration used to read telemetry settings. /// /// A instance if telemetry is enabled and properly configured for HTTP transport; /// otherwise, null. @@ -924,17 +926,17 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) /// /// The transport is HTTP (not STDIO) /// AZURE_MCP_COLLECT_TELEMETRY is not explicitly set to false - /// APPLICATIONINSIGHTS_CONNECTION_STRING environment variable is set + /// APPLICATIONINSIGHTS_CONNECTION_STRING is set /// /// The tracer provider includes ASP.NET Core and HttpClient instrumentation with filtering /// to avoid duplicate spans and telemetry loops. /// This telemetry configuration is intended for self-hosted scenarios where /// the MCP server is running in HTTP mode. This creates an independent telemetry pipeline using TracerProvider to export - /// traces to user-configured Application Insights instance only when the necessary environment variables are set. This also honors - /// the AZURE_MCP_COLLECT_TELEMETRY environment variable to allow users to disable telemetry collection if desired. Note that this is + /// traces to user-configured Application Insights instance only when the necessary configuration values are set. This also honors + /// the AZURE_MCP_COLLECT_TELEMETRY setting to allow users to disable telemetry collection if desired. Note that this is /// in addition to the telemetry configured in . /// - private static TracerProvider? AddIncomingAndOutgoingHttpSpans(ServiceStartOptions options) + private static TracerProvider? AddIncomingAndOutgoingHttpSpans(ServiceStartOptions options, IConfiguration configuration) { if (options.Transport != TransportTypes.Http) { @@ -949,11 +951,9 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) return null; } - string? collectTelemetry = Environment.GetEnvironmentVariable("AZURE_MCP_COLLECT_TELEMETRY"); - bool isTelemetryEnabled = string.IsNullOrWhiteSpace(collectTelemetry) || - (bool.TryParse(collectTelemetry, out bool shouldCollectTelemetry) && shouldCollectTelemetry); + bool isTelemetryEnabled = configuration.GetValue("AZURE_MCP_COLLECT_TELEMETRY", true); - string? connectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING"); + string? connectionString = configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]; if (!isTelemetryEnabled || string.IsNullOrWhiteSpace(connectionString)) { return null; diff --git a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/AuthenticationServiceCollectionExtensions.cs b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/AuthenticationServiceCollectionExtensions.cs index f0e4430e53..048ea26075 100644 --- a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/AuthenticationServiceCollectionExtensions.cs +++ b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/AuthenticationServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ // Licensed under the MIT License. using Microsoft.AspNetCore.Authentication; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Logging; @@ -41,7 +42,9 @@ public static IServiceCollection AddSingleIdentityTokenCredentialProvider(this I services.TryAddSingleton(sp => { var cloudConfig = sp.GetRequiredService(); + var configuration = sp.GetService(); CustomChainedCredential.CloudConfiguration = cloudConfig; + CustomChainedCredential.Configuration = configuration; return new SingleIdentityTokenCredentialProvider(sp.GetRequiredService()); }); diff --git a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs index 2ef1c89ba2..eb10285f13 100644 --- a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs +++ b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs @@ -6,6 +6,7 @@ using Azure.Identity; using Azure.Identity.Broker; using Azure.Mcp.Core.Helpers; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; namespace Azure.Mcp.Core.Services.Azure.Authentication; @@ -83,6 +84,20 @@ internal class CustomChainedCredential(string? tenantId = null, ILogger internal static IAzureCloudConfiguration? CloudConfiguration { get; set; } + /// + /// Configuration for reading settings. Set by DI container during service registration. + /// When set, configuration-based retrieval is preferred over direct environment variable access, + /// allowing non-environment sources (e.g. appsettings.json) to override values. + /// + internal static IConfiguration? Configuration { get; set; } + + /// + /// Reads a configuration value, preferring when available + /// and falling back to otherwise. + /// + private static string? GetConfigValue(string key) => + Configuration?[key] ?? Environment.GetEnvironmentVariable(key); + public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken) { _credential ??= CreateCredential(tenantId, _logger, forceBrowserFallback); @@ -103,13 +118,14 @@ public override ValueTask GetTokenAsync(TokenRequestContext request private static bool ShouldUseOnlyBrokerCredential() { - return EnvironmentHelpers.GetEnvironmentVariableAsBool(OnlyUseBrokerCredentialEnvVarName); + string? value = GetConfigValue(OnlyUseBrokerCredentialEnvVarName); + return value is "true" or "True" or "T" or "1"; } private static TokenCredential CreateCredential(string? tenantId, ILogger? logger = null, bool forceBrowserFallback = false) { // Check if AZURE_TOKEN_CREDENTIALS is explicitly set - string? tokenCredentials = Environment.GetEnvironmentVariable(TokenCredentialsEnvVarName); + string? tokenCredentials = GetConfigValue(TokenCredentialsEnvVarName); bool hasExplicitCredentialSetting = !string.IsNullOrEmpty(tokenCredentials); #if DEBUG @@ -122,7 +138,7 @@ private static TokenCredential CreateCredential(string? tenantId, ILogger(); // Check if we are running in a VS Code context. VSCODE_PID is set by VS Code when launching processes, and is a reliable indicator for VS Code-hosted processes. - bool isVsCodeContext = !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("VSCODE_PID")); + bool isVsCodeContext = !string.IsNullOrEmpty(GetConfigValue("VSCODE_PID")); if (isVsCodeContext && !hasExplicitCredentialSetting) { @@ -185,7 +201,7 @@ private static TokenCredential CreateCredential(string? tenantId, ILogger 0) { @@ -224,7 +240,7 @@ private static TokenCredential CreateBrowserCredential(string? tenantId, Authent private static ChainedTokenCredential CreateDefaultCredential(string? tenantId) { - string? tokenCredentials = Environment.GetEnvironmentVariable(TokenCredentialsEnvVarName); + string? tokenCredentials = GetConfigValue(TokenCredentialsEnvVarName); var credentials = new List(); // Handle specific credential targeting @@ -328,7 +344,7 @@ private static void AddWorkloadIdentityCredential(List credenti private static void AddManagedIdentityCredential(List credentials) { // Check if AZURE_CLIENT_ID is set for User-Assigned Managed Identity - string? clientId = Environment.GetEnvironmentVariable("AZURE_CLIENT_ID"); + string? clientId = GetConfigValue("AZURE_CLIENT_ID"); ManagedIdentityCredential managedIdentityCredential; if (!string.IsNullOrEmpty(clientId)) From 4d342f64beffaf384c44cc0ee898b4d698b4b1ae Mon Sep 17 00:00:00 2001 From: g2vinay <5430778+g2vinay@users.noreply.github.com> Date: Mon, 16 Mar 2026 10:07:50 -0700 Subject: [PATCH 2/4] Address feedback --- .../Server/Commands/ServiceStartCommand.cs | 40 ++++++++++++++++--- .../Authentication/CustomChainedCredential.cs | 3 +- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs index aca8d207d2..a03aee8e9c 100644 --- a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs +++ b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs @@ -198,9 +198,17 @@ public override async Task ExecuteAsync(CommandContext context, try { - // Build configuration from environment variables so AddIncomingAndOutgoingHttpSpans + // Build configuration using the same sources the host will use so AddIncomingAndOutgoingHttpSpans // has access to IConfiguration before the host DI container is constructed. + // This mirrors Host.CreateDefaultBuilder / WebApplication.CreateBuilder source order: + // appsettings.json → appsettings.{env}.json → environment variables. + string hostEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") + ?? Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT") + ?? "Production"; IConfiguration preHostConfiguration = new ConfigurationBuilder() + .SetBasePath(AppContext.BaseDirectory) + .AddJsonFile("appsettings.json", optional: true, reloadOnChange: false) + .AddJsonFile($"appsettings.{hostEnvironment}.json", optional: true, reloadOnChange: false) .AddEnvironmentVariables() .Build(); @@ -471,7 +479,8 @@ private IHost CreateHttpHost(ServiceStartOptions serverOptions) // Read once at host setup time — this value is process-wide and effectively static, // so there is no need to re-read it on every incoming request. // Default to false; the configuration value must parse to "true" to enable. - bool enableForwardedHeaders = builder.Configuration.GetValue("AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS"); + string? forwardedHeadersSetting = builder.Configuration["AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS"]; + bool enableForwardedHeaders = bool.TryParse(forwardedHeadersSetting, out bool parsedForwardedHeaders) && parsedForwardedHeaders; // Configure logging builder.Logging.ClearProviders(); @@ -840,7 +849,13 @@ private static void InitializeListingUrls(WebApplicationBuilder builder, Service throw new InvalidOperationException($"Explicit external binding is not supported for '{url}'."); } - if (isWildcard && !builder.Configuration.GetValue("ALLOW_INSECURE_EXTERNAL_BINDING")) + var allowInsecureExternalBindingRaw = builder.Configuration["ALLOW_INSECURE_EXTERNAL_BINDING"]; + bool allowInsecureExternalBinding = false; + if (!string.IsNullOrWhiteSpace(allowInsecureExternalBindingRaw)) + { + _ = bool.TryParse(allowInsecureExternalBindingRaw, out allowInsecureExternalBinding); + } + if (isWildcard && !allowInsecureExternalBinding) { throw new InvalidOperationException( $"External binding blocked for '{url}'. " + @@ -908,7 +923,9 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) // - The application or server's HTTP stack is not listening for non-HTTPS requests. // // Safe default to enable HTTPS redirection unless explicitly opted-out. - if (!app.Configuration.GetValue("AZURE_MCP_DANGEROUSLY_DISABLE_HTTPS_REDIRECTION")) + var disableHttpsRedirectionSetting = app.Configuration["AZURE_MCP_DANGEROUSLY_DISABLE_HTTPS_REDIRECTION"]; + var httpsRedirectionDisabled = bool.TryParse(disableHttpsRedirectionSetting, out var parsedValue) && parsedValue; + if (!httpsRedirectionDisabled) { app.UseHttpsRedirection(); } @@ -955,8 +972,19 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) return null; } - bool isTelemetryEnabled = configuration.GetValue("AZURE_MCP_COLLECT_TELEMETRY", true); - + string? telemetrySetting = configuration["AZURE_MCP_COLLECT_TELEMETRY"]; + bool isTelemetryEnabled; + if (string.IsNullOrWhiteSpace(telemetrySetting)) + { + // Preserve default behavior when the setting is not provided. + isTelemetryEnabled = true; + } + else if (!bool.TryParse(telemetrySetting, out isTelemetryEnabled)) + { + // Treat invalid/unknown values as telemetry disabled to avoid startup failures. + isTelemetryEnabled = false; + } + string? connectionString = configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]; if (!isTelemetryEnabled || string.IsNullOrWhiteSpace(connectionString)) { diff --git a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs index af5b682944..b918e55279 100644 --- a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs +++ b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs @@ -5,7 +5,6 @@ using Azure.Core; using Azure.Identity; using Azure.Identity.Broker; -using Azure.Mcp.Core.Helpers; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; @@ -97,7 +96,7 @@ internal class CustomChainedCredential(string? tenantId = null, ILogger /// Configuration for reading settings. Set by DI container during service registration. /// When set, configuration-based retrieval is preferred over direct environment variable access, - /// allowing non-environment sources (e.g. appsettings.json) to override values. + /// allowing values to come from non-environment sources (e.g. appsettings.json) in addition to environment variables. /// internal static IConfiguration? Configuration { get; set; } From 62fda133ae53007308a957a2f04ccda27f789143 Mon Sep 17 00:00:00 2001 From: g2vinay <5430778+g2vinay@users.noreply.github.com> Date: Mon, 16 Mar 2026 11:00:18 -0700 Subject: [PATCH 3/4] add creential unit tests. --- .../CustomChainedCredentialTests.cs | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Services/Azure/Authentication/CustomChainedCredentialTests.cs b/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Services/Azure/Authentication/CustomChainedCredentialTests.cs index 6898e72345..5cebf6cb6e 100644 --- a/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Services/Azure/Authentication/CustomChainedCredentialTests.cs +++ b/core/Azure.Mcp.Core/tests/Azure.Mcp.Core.UnitTests/Services/Azure/Authentication/CustomChainedCredentialTests.cs @@ -4,6 +4,7 @@ using System.Reflection; using Azure.Core; using Azure.Identity; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Xunit; @@ -400,6 +401,66 @@ public void PinnedCredentialMode_DoesNotAddDeviceCodeFallback_CreatesCredentialS Assert.IsAssignableFrom(credential); } + /// + /// Tests that when Configuration is set, token credentials are read from IConfiguration + /// rather than only from environment variables. + /// + [Fact] + public void Configuration_WhenSet_ReadsTokenCredentialsFromConfiguration() + { + // Arrange: env var cleared; IConfiguration provides the credential type + using var env = new EnvironmentScope("AZURE_TOKEN_CREDENTIALS"); + Environment.SetEnvironmentVariable("AZURE_TOKEN_CREDENTIALS", null); + + var credentialType = GetCustomChainedCredentialType(); + var configProp = credentialType.GetProperty("Configuration", + BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + Assert.NotNull(configProp); + + var config = new ConfigurationBuilder() + .AddInMemoryCollection(new Dictionary { ["AZURE_TOKEN_CREDENTIALS"] = "AzureCliCredential" }) + .Build(); + configProp.SetValue(null, config); + + try + { + // Act + var credential = CreateCustomChainedCredential(); + + // Assert + Assert.NotNull(credential); + Assert.IsAssignableFrom(credential); + } + finally + { + configProp.SetValue(null, null); + } + } + + /// + /// Tests that when Configuration is null, token credentials fall back to environment variables. + /// + [Fact] + public void Configuration_WhenNull_FallsBackToEnvironmentVariable() + { + // Arrange: Configuration is null; env var provides the credential type + using var env = new EnvironmentScope("AZURE_TOKEN_CREDENTIALS"); + Environment.SetEnvironmentVariable("AZURE_TOKEN_CREDENTIALS", "AzureCliCredential"); + + var credentialType = GetCustomChainedCredentialType(); + var configProp = credentialType.GetProperty("Configuration", + BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public); + Assert.NotNull(configProp); + configProp.SetValue(null, null); // Ensure Configuration is null + + // Act + var credential = CreateCustomChainedCredential(); + + // Assert + Assert.NotNull(credential); + Assert.IsAssignableFrom(credential); + } + /// /// Helper method to create CustomChainedCredential using reflection since it's an internal class. /// From 09d15b665793e1f099fa1199794760cc06511a97 Mon Sep 17 00:00:00 2001 From: g2vinay <5430778+g2vinay@users.noreply.github.com> Date: Mon, 16 Mar 2026 12:10:56 -0700 Subject: [PATCH 4/4] fix format issues. --- .../src/Areas/Server/Commands/ServiceStartCommand.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs index a44cfeeda3..a56fc73b04 100644 --- a/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs +++ b/core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs @@ -566,7 +566,6 @@ private IHost CreateHttpHost(ServiceStartOptions serverOptions) // Add a multi-user, HTTP context-aware caching strategy to isolate cache entries. services.AddHttpServiceCacheService(); - // Configure non-MCP controllers/endpoints/routes/etc. services.AddHealthChecks(); @@ -995,7 +994,7 @@ private static WebApplication UseHttpsRedirectionIfEnabled(WebApplication app) // Treat invalid/unknown values as telemetry disabled to avoid startup failures. isTelemetryEnabled = false; } - + string? connectionString = configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"]; if (!isTelemetryEnabled || string.IsNullOrWhiteSpace(connectionString)) {