diff --git a/Dockerfile b/Dockerfile index 2c57fdf516..c94883e0ac 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ # Build the runtime image FROM mcr.microsoft.com/dotnet/runtime-deps:10.0-alpine AS runtime +# Install libsecret so MSAL token-cache persistence works on Alpine Linux. +# Without it, InteractiveBrowserCredential throws MsalCachePersistenceException +# in headless environments (Docker, WSL without a running keyring daemon). +RUN apk add --no-cache libsecret + # Add build argument for publish directory ARG PUBLISH_DIR @@ -30,8 +35,10 @@ RUN if [ ! -f $EXECUTABLE_NAME ]; then \ echo "ERROR: $EXECUTABLE_NAME executable does not exist" && exit 1; \ fi -# Copy the server binary to a known location and make it executable +# Copy the server binary to a known location and make it executable. +# Also chmod the original executable name so users can invoke it directly +# inside the container (e.g. via --entrypoint or exec). COPY ${PUBLISH_DIR}/${EXECUTABLE_NAME} server-binary -RUN chmod +x server-binary && test -x server-binary +RUN chmod +x server-binary ${EXECUTABLE_NAME} && test -x server-binary && test -x ${EXECUTABLE_NAME} ENTRYPOINT ["./server-binary", "server", "start"] 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..b14565408f 100644 --- a/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs +++ b/core/Microsoft.Mcp.Core/src/Services/Azure/Authentication/CustomChainedCredential.cs @@ -175,7 +175,11 @@ private static TokenCredential CreateCredential(string? tenantId, ILogger +AZURE_CLIENT_ID= +AZURE_CLIENT_SECRET= +``` + +`AZURE_TOKEN_CREDENTIALS=prod` restricts the credential chain to `EnvironmentCredential`, `WorkloadIdentityCredential`, and `ManagedIdentityCredential`. This skips `InteractiveBrowserCredential` entirely, preventing errors caused by a missing GUI or keyring daemon inside the container. + +> [!IMPORTANT] +> Omitting `AZURE_TOKEN_CREDENTIALS=prod` in a Docker container causes the server to fall back to `InteractiveBrowserCredential`, which tries to initialize the MSAL token cache via `libsecret`. If no keyring daemon is running in the container, authentication fails with `Persistence check failed` / `libsecret-1.so.0` not found errors even though your service principal credentials are correct. + +**Alternative: Managed Identity (for Azure-hosted containers)** + +When running on Azure Container Instances, AKS, or App Service with a managed identity, set: + +```env +AZURE_TOKEN_CREDENTIALS=prod +# For user-assigned managed identity only: +AZURE_CLIENT_ID= +``` + ### CI/CD Pipelines For automated builds and deployments, set the following environment variables: @@ -93,6 +123,7 @@ For automated builds and deployments, set the following environment variables: export AZURE_CLIENT_ID="" export AZURE_CLIENT_SECRET="" export AZURE_TENANT_ID="" +export AZURE_TOKEN_CREDENTIALS=prod ``` ## Authentication Scenarios in Enterprise Environments