Skip to content

Commit 6c8a602

Browse files
lewingCopilot
andcommitted
Skip browser auth on WSL by default; DARC_FORCE_BROWSER_AUTH to override
On WSL2, InteractiveBrowserCredential.Authenticate() blocks forever without throwing: the browser opens on the Windows host but the OAuth redirect targets localhost in the WSL network namespace, which Windows cannot reach in default NAT mode. Detect WSL via the env vars WSL itself sets and route straight to device code. Users who have configured wslu + mirrored networking can opt back into browser flow with DARC_FORCE_BROWSER_AUTH=1. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent bb914a3 commit 6c8a602

1 file changed

Lines changed: 23 additions & 0 deletions

File tree

src/Maestro/Maestro.Common/AppCredentials/CachedInteractiveBrowserCredential.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,29 @@ public CachedInteractiveBrowserCredential(
5858
return Task.CompletedTask;
5959
},
6060
});
61+
62+
// On WSL the interactive browser flow opens a browser on the Windows host, but the
63+
// OAuth redirect targets localhost in the WSL network namespace where MSAL's listener
64+
// is bound. Windows localhost != WSL2 localhost, so the redirect never arrives and
65+
// _browserCredential.Authenticate() blocks forever without throwing. Detect WSL up
66+
// front via the env vars WSL itself sets and skip straight to device code.
67+
if (IsWslEnvironment())
68+
{
69+
Interlocked.Exchange(ref _isDeviceCodeFallback, 1);
70+
}
71+
}
72+
73+
private static bool IsWslEnvironment()
74+
{
75+
// Escape hatch for users who have configured WSL2 for browser-based auth
76+
// (wslu + mirrored networking, or equivalent). Set DARC_FORCE_BROWSER_AUTH=1.
77+
if (string.Equals(Environment.GetEnvironmentVariable("DARC_FORCE_BROWSER_AUTH"), "1", StringComparison.Ordinal))
78+
{
79+
return false;
80+
}
81+
82+
return !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WSL_DISTRO_NAME"))
83+
|| !string.IsNullOrEmpty(Environment.GetEnvironmentVariable("WSL_INTEROP"));
6184
}
6285

6386
public override AccessToken GetToken(TokenRequestContext requestContext, CancellationToken cancellationToken)

0 commit comments

Comments
 (0)