microsoft / microsoft/artifacts-credprovider

[Bug]: MSAL Silent auth crashes with wam_runtime_init_failed on headless Linux (aarch64), never reads plain-text MSAL cache

Open
#702 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug external keep work-around
Dominant language
C#
Stars
947
Forks
728
PR merge metrics
No merged PRs in 30d

Description

Description

On headless Linux (Debian 12, aarch64), the MSAL Silent token provider crashes unconditionally with wam_runtime_init_failed before it can enumerate MSAL accounts or read the plain-text token cache at ~/.local/.IdentityService/msal.cache. The exception propagates out of GetAccountsInternalAsync and kills the entire silent auth attempt. The credential provider then falls through to browser (fails — no display) and device code (times out in non-interactive mode), ultimately returning "could not acquire credentials" — even though a valid access token and refresh token are present in the MSAL cache from a prior dotnet restore --interactive run.

Contrast: a second feed in the same NuGet.Config that has a cached entry in SessionTokenCache.dat works immediately — MSAL is never invoked. This confirms the environment and network are not at fault.

Environment (OS/platform or image)
  • OS: Debian GNU/Linux 12 (bookworm)
  • Architecture: aarch64
  • Kernel: 6.12.54-linuxkit
  • Environment: Headless devcontainer — no D-Bus user session, no keyring daemon, no display
  • Credential provider install: curl -fsSL https://aka.ms/install-artifacts-credprovider.sh | bash (broker-enabled build, v2.0.2+d0f3d8d)
  • MSAL.NET version: 4.77.1.0 (from exception header)
Tool versions
$ dotnet --version
8.0.422

$ dotnet --list-sdks
8.0.422 [/usr/share/dotnet/sdk]

$ dotnet --list-runtimes
Microsoft.AspNetCore.App 8.0.28 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 8.0.28 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Client/protocol path in use

Dotnet tool invocation

Credential Provider logs

Steps to reproduce

  1. Install the credential provider via the standard install script (broker-enabled build).
  2. Authenticate once interactively via dotnet restore --interactive, completing the device code flow. This populates ~/.local/.IdentityService/msal.cache with a valid access token and refresh token for an Azure DevOps Artifacts feed.
  3. Subsequently run dotnet restore (non-interactive) for a feed that has no entry in SessionTokenCache.dat.
  4. Observe warnings: "Using plain-text fallback token cache" followed by "could not acquire credentials".

To reproduce directly, invoke the credential provider with verbose output:

~/.nuget/plugins/netcore/CredentialProvider.Microsoft/CredentialProvider.Microsoft \
  -V Verbose -C \
  -U "https://pkgs.dev.azure.com/<org>/_packaging/<feed>/nuget/v3/index.json"

Full -V Verbose output from the direct invocation above. Key sequence:

[Verbose] Could not find cached SessionToken for https://pkgs.dev.azure.com/<org>/...
[Verbose] Found AAD Authority from 401 headers: https://login.windows.net/<tenant>
[Warning] Warning: Cannot persist Microsoft authentication token cache securely!
[Warning] Warning: Using plain-text fallback token cache
[Verbose] VstsCredentialProvider - Attempting to acquire bearer token using provider 'MSAL Silent'
[Verbose] VstsCredentialProvider - Bearer token provider 'MSAL Silent' failed with exception:
MSAL.NetCore.4.77.1.0.MsalClientException:
	ErrorCode: wam_runtime_init_failed
Microsoft.Identity.Client.MsalClientException: The type initializer for 'Microsoft.Identity.Client.NativeInterop.API' threw an exception.
 ---> System.TypeInitializationException: The type initializer for 'Microsoft.Identity.Client.NativeInterop.API' threw an exception.
 ---> System.PlatformNotSupportedException: Operation is not supported on this platform.
   at Microsoft.Identity.Client.NativeInterop.LinuxPlatformUtils.GetPackagePathAndSetEnvironmentVariables()
   at Microsoft.Identity.Client.NativeInterop.API..cctor()
   at Microsoft.Identity.Client.NativeInterop.Module.AddRef(String handleName)
   at Microsoft.Identity.Client.NativeInterop.Core..ctor()
   at Microsoft.Identity.Client.Platforms.Features.RuntimeBroker.RuntimeBroker.<>c.<.cctor>b__26_0()
   at Microsoft.Identity.Client.Platforms.Features.RuntimeBroker.RuntimeBroker.IsBrokerInstalledAndInvokable(AuthorityType authorityType)
   at Microsoft.Identity.Client.ClientApplicationBase.GetAccountsFromBrokerAsync(...)
   at Microsoft.Identity.Client.ClientApplicationBase.GetAccountsInternalAsync(...)
   at Microsoft.Artifacts.Authentication.MsalSilentTokenProvider.GetTokenAsync(TokenRequest tokenRequest, CancellationToken)
[Verbose] VstsCredentialProvider - Attempting to acquire bearer token using provider 'MSAL Broker Interactive'
[Verbose] VstsCredentialProvider - Bearer token provider 'MSAL Broker Interactive' failed with exception:
  (same wam_runtime_init_failed)
[Verbose] VstsCredentialProvider - Attempting to acquire bearer token using provider 'MSAL Interactive'
  (linux_xdg_open_failed — no display)
[Verbose] VstsCredentialProvider - Attempting to acquire bearer token using provider 'MSAL Device Code'
  (prompt shown, task cancelled — non-interactive context)
[Verbose] VstsCredentialProvider - Could not obtain credentials
[Warning] The plugin credential provider could not acquire credentials.
Additional context

Workaround

Install the brokerless build, which ships without Microsoft.Identity.Client.NativeInterop.dll and does not attempt WAM initialization:

ARCH=$(uname -m | sed 's/aarch64/arm64/;s/x86_64/x64/')
curl -fsSL \
  "https://github.com/microsoft/artifacts-credprovider/releases/latest/download/Microsoft.linux-${ARCH}.Brokerless.NuGet.CredentialProvider.tar.gz" \
  | tar xz -C "$HOME/.nuget/plugins" --strip-components=3

Note: the default install script (aka.ms/install-artifacts-credprovider.sh) has no flag to select the brokerless build — manual installation is required.

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.

Research direction

Start at Microsoft.Artifacts.Authentication.MsalSilentTokenProvider.GetTokenAsync and trace the MSAL broker/native interop initialization shown in the exception, comparing broker-enabled and brokerless packaging on headless Linux. Done means MSAL Silent no longer aborts with wam_runtime_init_failed on aarch64 and can use the existing plain-text cache without requiring a display.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
authentication, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.