Skip to content

Integrate Config based env retrieval#1978

Open
g2vinay wants to merge 6 commits intomicrosoft:mainfrom
g2vinay:feature/config-based-env-retrieval
Open

Integrate Config based env retrieval#1978
g2vinay wants to merge 6 commits intomicrosoft:mainfrom
g2vinay:feature/config-based-env-retrieval

Conversation

@g2vinay
Copy link
Contributor

@g2vinay g2vinay commented Mar 10, 2026

No description provided.

g2vinay added 2 commits March 9, 2026 21:55
…ls 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.
Copy link

@MontaEllis8 MontaEllis8 left a comment

Choose a reason for hiding this comment

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

✅ Code Review 通过

代码审查通过,建议合并。

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Integrates IConfiguration-based settings retrieval into authentication credential selection and server startup, reducing direct Environment.GetEnvironmentVariable usage and centralizing settings access through configuration.

Changes:

  • Add IConfiguration support to CustomChainedCredential and prefer configuration values when available.
  • Wire IConfiguration into CustomChainedCredential during DI registration.
  • Switch several server startup settings (telemetry, URLs, forwarded headers, HTTPS redirect opt-out) from direct env-var reads to IConfiguration.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.

File Description
core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs Adds configuration-backed value lookup for credential chain behavior.
core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/AuthenticationServiceCollectionExtensions.cs Passes IConfiguration from DI into CustomChainedCredential static state.
core/Microsoft.Mcp.Core/src/Areas/Server/Commands/ServiceStartCommand.cs Uses IConfiguration for multiple server startup toggles and telemetry settings.

Copy link
Member

@anuchandy anuchandy left a comment

Choose a reason for hiding this comment

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

Thanks Vinay! @g2vinay, these changes route env var reads through IConfiguration, but most of the values here are env var conventions by design - so wondering if this routing is necessary. Since it shifts expectations around how these are configured, it might be worth holding off on including this in GA.

/// When set, configuration-based retrieval is preferred over direct environment variable access,
/// allowing values to come from non-environment sources (e.g. appsettings.json) in addition to environment variables.
/// </summary>
internal static IConfiguration? Configuration { get; set; }
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if IConfiguration indirection layer we've here earn its keep? -

  1. "AZURE_CLIENT_ID" is a standard Azure Identity convention. The EnvironmentCredential in the same chain reads it directly from env via EnvironmentCredentialOptions - routing our read through IConfiguration while the azure-identity's own read bypasses it creates inconsistency within the same credential chain.
  2. "VSCODE_PID" is process introspection set by VS Code it will never appear in appsettings.json.

These values are lazily initialized and cached, so env reads happen once per instance - IConfiguration indirection doesn't improve caching or correctness.

My two cents, I'd lean toward keeping Environment.GetEnvironmentVariable as-is. If there's a specific scenario where appsettings.json sourcing is needed for certain values later, we could scope the change to just that variable rather than adding a blanket IConfiguration layer.

Copy link
Contributor Author

@g2vinay g2vinay Mar 16, 2026

Choose a reason for hiding this comment

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

I assume, @srnagar's direction was to make it similar to how we support Configuration in Azure Core in Java Azure SDKs.
Read from both code level config, properties, env var etc.
If that's still the goal, then the code level can override the env var, which is fine, as it won't regress users.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can add this selectively too, by design we can exclude certain areas where we want to restrict to env var only.
Will bring downside of incosnsitency, but if its justified by design, its fine, for Credential purposes, I don't see strong reason to restrict it, its fine to support config there too.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I was trying to understand the general pattern libs use.

Taking the telemetry SDK as an example: APPLICATIONINSIGHTS_CONNECTION_STRING (ALL_CAPS) is a flat "env var" read directly via Environment.GetEnvironmentVariable, not through IConfiguration.

The appsettings.json equivalent is the hierarchical ApplicationInsights:ConnectionString section, which maps to ApplicationInsights__ConnectionString (double underscore) "env-var" for IConfiguration resolution.

So my main point was that reading ALL_CAPS "env vars" through IConfiguration is uncommon - users understand IConfiguration work with the double-underscore "env var" form of a hierarchical section. That said, I don't see a concrete issue with us supporting ALL_CAPS via appsettings.json - yet.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, then perhaps we can also honor the double-underscore format as best practice.

out bool parsedEnvVar)
&& parsedEnvVar;
// Default to false; the configuration value must parse to "true" to enable.
string? forwardedHeadersSetting = builder.Configuration["AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS"];
Copy link
Member

Choose a reason for hiding this comment

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

So we're now reading ALLOW_INSECURE_EXTERNAL_BINDING, AZURE_MCP_DANGEROUSLY_DISABLE_HTTPS_REDIRECTION, and AZURE_MCP_DANGEROUSLY_ENABLE_FORWARDED_HEADERS via WebApplicationBuilder - meaning they can now be set via "appsettings.json". These are security-sensitive opt-ins, so this is worth scrutinizing: a checked-in config file could accidentally enable insecure settings, whereas env vars require explicit runtime intent. Would be good to get a read from the security folks before we settle on this.

Tagging Xiang, Srikanta - \cc @xiangyan99 , @srnagar

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We can opt to selectively restrict it to env here by design.

}

string? connectionString = Environment.GetEnvironmentVariable("APPLICATIONINSIGHTS_CONNECTION_STRING");
string? connectionString = configuration["APPLICATIONINSIGHTS_CONNECTION_STRING"];
Copy link
Member

Choose a reason for hiding this comment

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

Routing through IConfiguration appears to unlock setting APPLICATIONINSIGHTS_CONNECTION_STRING via appsettings.json, but this flat key is an env var convention.

Comment on lines +108 to +109
private static string? GetConfigValue(string key) =>
Configuration?[key] ?? Environment.GetEnvironmentVariable(key);
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 make this check a bit more verbose as there's a different between Configuration is null and fallback to Environment.GetEnvironmentVariable and Configuration returned null from the lookup, as Configuration will fallback to looking at Environment.GetEnvironmentVariable.

Suggested change
private static string? GetConfigValue(string key) =>
Configuration?[key] ?? Environment.GetEnvironmentVariable(key);
private static string? GetConfigValue(string key) =>
(Configuration == null)
? Environment.GetEnvironmentVariable(key)
: Configuration[key];

@anuchandy anuchandy added the Do Not Merge Do Not Merge / WIP PRs label Mar 17, 2026
@joshfree joshfree added this to the 2026-04 milestone Mar 17, 2026
@joshfree joshfree moved this from Untriaged to In Progress in Azure MCP Server Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Do Not Merge Do Not Merge / WIP PRs

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

6 participants