dotnet / dotnet/arcade-services

darc login fails on WSL when gnome-keyring/D-Bus secrets service is unavailable

Open
#6,060 0 comments 0 reactions 0 assignees View on GitHub
Copilot suitable
Dominant language
C#
Stars
86
Forks
86
Avg merge
1d 8h
Merged PRs (30d)
35

Description

## Description

`darc login` and all authenticated darc commands fail hard on WSL (Windows Subsystem for Linux) when the D-Bus secrets service (`org.freedesktop.secrets`) is not running. The MSAL token cache persistence check throws `MsalCachePersistenceException` before any authentication can occur, with no fallback to `AzureCliCredential` or in-memory caching.

## Error

```
fail: Authentication failed: DeviceCodeCredential authentication failed: Persistence check failed.
Reason: An error was encountered while saving secret to keyring in the Storage
domain:'164' code:'1' message:'Could not connect: No such file or directory'
```

## Root Cause

In `CachedInteractiveBrowserCredential`, both `InteractiveBrowserCredential` and `DeviceCodeCredential` are constructed with `TokenCachePersistenceOptions` in the constructor (line 43-48). When `GetTokenAsync` is called, the MSAL cache helper calls `VerifyPersistence()` which tries to write to `libsecret` via D-Bus. If no secrets service is registered on D-Bus, this throws before any token acquisition is attempted.

The `CacheAuthenticationRecord` method (line ~113) does catch `MsalCachePersistenceException` and recreate the credentials without persistence options, but this fallback only applies to the `Authenticate` path during initial login — not to `GetToken`/`GetTokenAsync` which is what `get-channels` and other commands use after login.

Additionally, `LoginOperation.ExecuteAsync` catches the exception but only logs it — it does not attempt alternative credential types like `AzureCliCredential`.

## Workaround

Setting up D-Bus and gnome-keyring in WSL:

```bash
# Ensure /run/user/ exists (may need sudo)
sudo mkdir -p /run/user/$(id -u) && sudo chown $USER:$USER /run/user/$(id -u) && sudo chmod 700 /run/user/$(id -u)

# Install gnome-keyring and libsecret
sudo apt-get install -y gnome-keyring libsecret-1-0

# Add to .bashrc
export XDG_RUNTIME_DIR="/run/user/$(id -u)"
if [ -S "$XDG_RUNTIME_DIR/bus" ]; then
export DBUS_SESSION_BUS_ADDRESS="unix:path=$XDG_RUNTIME_DIR/bus"
fi
if ! pgrep -u "$USER" gnome-keyring-daemon &>/dev/null; then
gnome-keyring-daemon --start --foreground --components=secrets &>/dev/null &
fi
```

## Suggested Fix

Consider one or more of:

1. **Graceful fallback to `AzureCliCredential`** — if the user has `az` CLI logged in, use that when the keyring is unavailable
2. **Fallback to plaintext file cache** — use `TokenCachePersistenceOptions { UnsafeAllowUnencryptedStorage = true }` when `VerifyPersistence` fails, with a warning
3. **Catch `MsalCachePersistenceException` in `GetTokenAsync`** — the existing catch in `CacheAuthenticationRecord` only covers the initial auth path, not subsequent token acquisitions

## Environment

- WSL 2.6.3 on Windows
- Ubuntu 22.04
- darc 1.1.0-beta.26156.2
- .NET 8.0.24 runtime

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.