microsoft / microsoft/mcp

[BUG] HTTP incoming auth configuration undocumented for Azure.Mcp.Server 3.0.0-beta.3 (hosted as HTTP service in AKS)

Open
#2,459 1 comment 0 reactions 1 assignee View on GitHub

Nobody has claimed this yet.

bug customer-reported needs-team-attention remote-mcp server-Azure.Mcp tools-Authentication
Dominant language
C#
Stars
3.7k
Forks
624
Avg merge
2d 20h
Merged PRs (30d)
220

Description

### Describe the bug

When running Azure.Mcp.Server (image mcr.microsoft.com/azure-sdk/azure-mcp:latest, version 3.0.0-beta.3) with --transport http in a container (AKS), the server enforces HTTP incoming authentication but provides no documented way to configure the Entra ID tenant, audience, or valid issuers needed to validate inbound bearer tokens.

As a result:

All inbound requests fail with 401 Unauthorized
The startup log shows IDX10204: Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace AND validationParameters.ValidIssuers is null or empty
/.well-known/oauth-protected-resource returns a malformed issuer URL (https://login.microsoftonline.com//v2.0) indicating the tenant was never injected
The azmcp server start --help output shows only --outgoing-auth-strategy (for MCP → Azure) and --dangerously-disable-http-incoming-auth. There is no --incoming-auth-* family of flags, and no documented configuration keys for HTTP incoming auth.

The TROUBLESHOOTING.md "Using Azure Entra ID with Docker" section only covers stdio local development with ~/.azure volume mounts — not HTTP hosting.

### Expected behavior

Documented, first-class configuration for HTTP incoming auth when running as a hosted HTTP service, including at minimum:

Tenant ID
Audience / Client ID (App Registration)
Valid issuers (v1.0 and v2.0)
Required scopes
This should be configurable via one of:

CLI flags `(e.g. --incoming-auth-tenant-id, --incoming-auth-audience, --incoming-auth-strategy EntraId)`
Environment variables (documented names and config binding paths)
`appsettings.json` section with a documented schema
`/.well-known/oauth-protected-resource` should emit a fully-formed issuer URL containing the configured tenant ID.

Inbound requests carrying a valid Entra ID bearer token for the configured audience and tenant should be authenticated and authorized.

### Actual behavior

azmcp server start runs an HTTP server with incoming auth enabled by default but no documented way to configure it.
The token validator initializes with empty ValidIssuers / ValidAudiences and rejects every bearer token with IDX10204.
/.well-known/oauth-protected-resource returns

`{
"resource": "http://",
"authorization_servers": ["https://login.microsoftonline.com//v2.0"],
"scopes_supported": ["/Mcp.Tools.ReadWrite"],
"bearer_methods_supported": ["header"],
"resource_documentation": "https://github.com/Microsoft/mcp"
}`

Note the empty tenant (//v2.0) and leading-slash scope (/Mcp.Tools.ReadWrite).
Common ASP.NET Core and plausible MCP-specific env vars are ignored:
AzureAd__TenantId, AzureAd__ClientId, AzureAd__Audience
AzureAd__ValidIssuers__0, AzureAd__ValidIssuers__1
AzureAd__Instance
EntraId__TenantId, EntraId__ClientId, EntraId__Audience
AZURE_VALID_ISSUERS, AZURE_TENANT_ID, AZURE_CLIENT_ID
The only way to successfully serve HTTP traffic is to pass --dangerously-disable-http-incoming-auth, which is unacceptable for production use.
Error observed in server logs:

`Microsoft.IdentityModel.Tokens.SecurityTokenInvalidIssuerException: IDX10204:
Unable to validate issuer. validationParameters.ValidIssuer is null or whitespace
AND validationParameters.ValidIssuers is null or empty.
Bearer was not authenticated. Failure message: IDX10204: ...`

Client-side 401 response:

`HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="",
resource_metadata="http:///.well-known/oauth-protected-resource",
error="invalid_token",
error_description="The issuer 'https://sts.windows.net//' is invalid"`

### Reproduction Steps

Environment
Image: mcr.microsoft.com/azure-sdk/azure-mcp:latest
Version: Azure.Mcp.Server 3.0.0-beta.3
Runtime: Azure Kubernetes Service (AKS) with Workload Identity
Ingress: NGINX (HTTP)

Steps
Deploy azure-mcp:latest as an HTTP service in Kubernetes with the following args:

```
args:
- "--transport"
- "http"
- "--mode"
- "namespace"
- "--outgoing-auth-strategy"
- "UseHostingEnvironmentIdentity"
- "--read-only"
```

Attempt to configure incoming auth via environment variables (all variants tested):

```
env:
- name: AZURE_TENANT_ID
value: ""
- name: AZURE_CLIENT_ID
value: ""
- name: AzureAd__TenantId
value: ""
- name: AzureAd__ClientId
value: ""
- name: AzureAd__Audience
value: "api://"
- name: AzureAd__ValidIssuers__0
value: "https://sts.windows.net//"
- name: AzureAd__ValidIssuers__1
value: "https://login.microsoftonline.com//v2.0"
- name: EntraId__TenantId
value: ""
- name: EntraId__Audience
value: "api://"
```

Obtain a valid Entra ID access token (e.g., via az account get-access-token --resource https://management.azure.com).

Call the MCP server:
`curl -i -H "Authorization: Bearer $TOKEN" http:///`

Observe 401 Unauthorized with IDX10204 in server logs.

Verify /.well-known/oauth-protected-resource returns an issuer URL with an empty tenant segment:
`curl -s http:///.well-known/oauth-protected-resource`

Additional diagnostics
Inspecting the binary (strings /mcp-server/server-binary) reveals:
IsEntraIDAuthEnabled property exists
CreateIncomingAuthDisabledHttpHost confirms the disable flag path
Internal references to k__BackingField suggesting an EntraId config section exists, but its binding path (env var prefix / JSON section) is not documented
appsettings.json in the image contains only 3 lines and no auth-related config:
```
{
"RootCommandGroupName": "azmcp",
"Name": "Azure.Mcp.Server",
"DisplayName": "Azure MCP Server"
}
```

ASK:

Please document (or add) the supported mechanism for configuring HTTP incoming auth in Azure.Mcp.Server when running as a hosted HTTP service. Examples of what would be helpful:

An example docker run / Kubernetes manifest showing incoming auth env vars or CLI flags
The exact configuration binding path (e.g., IncomingAuth:EntraId:TenantId → IncomingAuth__EntraId__TenantId)
Required App Registration configuration (Application ID URI, exposed scopes, audience version)
Whether v1.0 tokens (ARM audience) are ever accepted, or if only v2.0 tokens against a custom App Registration are supported
Until this is documented, --dangerously-disable-http-incoming-auth is effectively required for any hosted HTTP deployment, which contradicts the flag's stated intent.

### Environment

AKS

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.