Skip to content

feat(provision): MSAL browser auth for headless Linux via wslview shim#259

Merged
szymonos merged 4 commits into
mainfrom
feat/msal-browser-auth
Jul 23, 2026
Merged

feat(provision): MSAL browser auth for headless Linux via wslview shim#259
szymonos merged 4 commits into
mainfrom
feat/msal-browser-auth

Conversation

@szymonos

@szymonos szymonos commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add a wslview shim (.assets/config/bin/wslview) that MSAL.NET execs as its last-resort browser opener on headless Linux (WSL, devcontainers, SSH VMs). Instead of opening a browser it prints the sign-in URL for CTRL+Click, keeping MSAL's localhost redirect listener alive — so Connect-AzAccount / Connect-MgGraph use the browser auth-code flow instead of device code (which the Entra Conditional Access policy blocks).
  • Shim install is gated on $headlessNoOpener (Linux AND no real MSAL opener AND no genuine wslview on PATH) — desktop Linux with a real xdg-open/browser is left untouched. wslview is a binary name hardcoded in MSAL.NET (NetCorePlatformProxy.cs), not a wslu dependency, so wslu's 2025-03 archival doesn't affect it.
  • Disable EnableLoginByWam in the orchestrators (linux_setup.sh, wsl_setup.ps1), right after the Az modules are installed under the az scope. This is deliberately not gated on $headlessNoOpener: the WAM broker (msalruntime.so) is non-functional on all Linux, so interactive Az login must always fall through to the browser flow there. It must run after Az install because Set-AzConfig needs Az.Accounts — the earlier attempt (in setup_profile_user.ps1, which runs before Az install to trust PSGallery) silently no-op'd on fresh setups. Idempotent: skips the write when already off.
  • Persist DOTNET_SYSTEM_NET_DISABLEIPV6=1 in the profile for containers (MSAL binds the redirect listener on IPv6 but VS Code forwards IPv4).
  • fix: setup_gh_repos.sh crashed on rerun (cloned: unbound variable under set -u) — the flag was only assigned on a successful clone. Initialize cloned=false and test the value.
  • Record two design/lessons.md postmortems: (1) MSAL's fixed reply port (8400) shadowed by a Windows-side listener; (2) a provisioning step gated on a not-yet-installed module silently no-ops (the WAM bug).

Test plan

  • make lint-diff — all pre-commit hooks green
  • Generated pwsh for the WAM-disable verified to parse/run through the wsl.exe -- pwsh -c reparse (avoids $false, which expands to empty across that boundary — used a truthy guard + numeric 0)
  • setup_gh_repos.sh rerun path (all repos cloned) no longer trips set -u
  • Reviewer: Connect-AzAccount from a fresh WSL distro provisioned by this branch — browser flow completes, no device code, Get-AzConfig -EnableLoginByWam shows False/CurrentUser
  • Reviewer: confirm desktop Linux with a real opener gets no shim installed

🤖 Generated with Claude Code

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a wslview shim and related profile tweaks to enable MSAL/MSAL.NET interactive browser auth-code flows on headless Linux environments (notably WSL/devcontainers), avoiding device-code auth that is blocked by Conditional Access. Also documents an MSAL redirect-port collision diagnosis lesson learned.

Changes:

  • Add .assets/config/bin/wslview shim that prints the MSAL auth URL to the controlling terminal (CTRL+Click flow) instead of attempting to open a GUI browser.
  • Update .assets/provision/setup_profile_user.ps1 to conditionally install the shim (when no earlier MSAL opener exists), disable WAM in devcontainers, and persist a devcontainer IPv6 loopback workaround.
  • Add a postmortem entry in design/lessons.md covering fixed reply-port (8400) collisions causing “Working…” hangs.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
design/lessons.md Adds a new lessons-learned entry documenting an MSAL/Az reply-port collision diagnosis and remediation.
.assets/provision/setup_profile_user.ps1 Conditionally installs a wslview shim for MSAL, disables WAM in containers, and adds a devcontainer IPv6 loopback environment fix to the PowerShell profile.
.assets/config/bin/wslview New Bash shim that prints the MSAL auth URL to the controlling terminal so interactive login can proceed without a browser opener.

Comment thread .assets/provision/setup_profile_user.ps1

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

.assets/provision/setup_profile_user.ps1:101

  • WAM can be disabled even if the wslview shim was not installed (e.g., shim source missing due to CWD mismatch or install failure). That leaves a headless environment with no opener and WAM disabled, breaking interactive auth. Gate WAM disable on the shim actually being present.
if ($headlessNoOpener -and (Get-Module Az.Accounts -ListAvailable)) {

Comment thread .assets/provision/setup_profile_user.ps1
Comment thread .assets/provision/setup_profile_user.ps1 Outdated
@szymonos
szymonos force-pushed the feat/msal-browser-auth branch 3 times, most recently from 3f597f4 to 792db77 Compare July 23, 2026 17:42
@szymonos
szymonos requested a review from Copilot July 23, 2026 17:43

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 3 comments.

Comment thread wsl/wsl_setup.ps1 Outdated
Comment thread .assets/scripts/linux_setup.sh
Comment thread .assets/provision/setup_profile_user.ps1

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Comment thread .assets/provision/setup_gh_repos.sh
…p_gh_repos

A failed git clone (network/DNS/outage) left `cloned` false, so the
"all repos already cloned" summary printed even when a repo was actually
missing. Only clone when the dir is absent, and track real failures
separately so the success message is suppressed on genuine errors.

Co-Authored-By: Claude <noreply@anthropic.com>
@szymonos
szymonos merged commit 044eae9 into main Jul 23, 2026
3 checks passed
@szymonos
szymonos deleted the feat/msal-browser-auth branch July 23, 2026 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants