zed/script/test-wsl-sandbox.ps1
MartinYe1234 dfd44a45dd
Add Windows terminal sandboxing via WSL (#58971)
Summary

- Adds Windows agent terminal sandboxing by routing commands through WSL
and Bubblewrap.
- Supports native Windows and WSL project paths, including elevated
write grants for WSL paths.
- Shows a confirmation prompt to turn off sandboxing when WSL sandbox
setup is unavailable.

This builds on the work in the sandbox-linux branch.

Closes AI-376

Release Notes:

- Added Windows terminal sandboxing for agent commands when sandboxing
is enabled.

---------

Co-authored-by: cameron <cameron.studdstreet@gmail.com>
Co-authored-by: Richard Feldman <oss@rtfeldman.com>
Co-authored-by: zed-zippy[bot] <234243425+zed-zippy[bot]@users.noreply.github.com>
2026-06-17 21:07:29 +00:00

101 lines
3.9 KiB
PowerShell

#!/usr/bin/env pwsh
# Provision the default WSL distro for the Windows sandbox behavior tests and
# run them. The Windows analog of running `cargo xtask sandbox-tests` on Linux.
#
# What it does:
# 1. Checks that WSL is installed.
# 2. (Unless -NoProvision) installs `bubblewrap` into the default distro and
# enables unprivileged user namespaces, so the sandbox can actually be
# enforced. Without both, the helper can only SKIP the enforcement checks —
# it can't verify a sandbox that was never set up. On Ubuntu 24.04 (the
# current default WSL distro) user namespaces are restricted by AppArmor by
# default, which is exactly why this step is needed.
# 3. Runs `cargo xtask wsl-sandbox-tests`, which builds and runs
# `wsl_sandbox_test_helper` against the real WSL/Bubblewrap sandbox.
#
# By default it requires the sandbox to actually be enforced (so a broken setup
# fails loudly instead of silently skipping). Pass -AllowSkip to keep the
# helper's default skip-when-unenforceable behavior.
#
# Notes:
# * Provisioning runs as root via `wsl -u root`, so it needs no sudo password.
# * Auto-provisioning only supports apt-based distros (Ubuntu/Debian). For
# others, install `bubblewrap` yourself and re-run with -NoProvision.
# * The user-namespace sysctl is set for the running WSL VM only; it resets
# after `wsl --shutdown`.
# * If the network checks are skipped, Windows Firewall may be blocking the
# test's local listener; that only affects the network assertions.
#
# Usage:
# ./script/test-wsl-sandbox.ps1
# ./script/test-wsl-sandbox.ps1 -NoProvision
# ./script/test-wsl-sandbox.ps1 -Release
# ./script/test-wsl-sandbox.ps1 -AllowSkip
[CmdletBinding()]
param(
[switch]$NoProvision,
[switch]$Release,
[switch]$AllowSkip
)
$ErrorActionPreference = "Stop"
if (-not (Get-Command wsl.exe -ErrorAction SilentlyContinue)) {
Write-Error "wsl.exe was not found. Install WSL (https://learn.microsoft.com/windows/wsl/install) and try again."
}
# Run a command in the default WSL distro as root, throwing on failure.
function Invoke-WslRoot {
param([Parameter(Mandatory = $true)][string]$Script)
& wsl.exe -u root -- sh -c $Script
if ($LASTEXITCODE -ne 0) {
throw "WSL command failed (exit $LASTEXITCODE): $Script"
}
}
# Run a command in the default WSL distro as the default user, returning its
# exit code instead of throwing.
function Test-Wsl {
param([Parameter(Mandatory = $true)][string]$Script)
& wsl.exe -- sh -lc $Script *> $null
return $LASTEXITCODE
}
if (-not $NoProvision) {
Write-Host "==> Provisioning the default WSL distro for sandbox testing"
if ((Test-Wsl "command -v apt-get >/dev/null 2>&1") -eq 0) {
Write-Host " Installing bubblewrap (apt-get)..."
Invoke-WslRoot "apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y bubblewrap"
}
else {
Write-Warning "Auto-provisioning only supports apt-based distros. Install 'bubblewrap' in your default WSL distro manually, then re-run with -NoProvision."
}
Write-Host " Enabling unprivileged user namespaces (for this WSL VM session)..."
# Older kernels lack this key (the AppArmor restriction simply isn't
# present), so don't treat a missing key as an error.
Invoke-WslRoot "sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 2>/dev/null || true"
}
if ((Test-Wsl "command -v bwrap >/dev/null 2>&1") -ne 0) {
Write-Warning "bwrap is not installed in the default WSL distro; the sandbox cannot be enforced. Install 'bubblewrap' (or run without -NoProvision)."
}
$repoRoot = Split-Path -Parent $PSScriptRoot
Push-Location $repoRoot
try {
$xtaskArgs = @("xtask", "wsl-sandbox-tests")
if (-not $AllowSkip) { $xtaskArgs += "--require-enforced" }
if ($Release) { $xtaskArgs += "--release" }
Write-Host "==> Running: cargo $($xtaskArgs -join ' ')"
& cargo @xtaskArgs
$exitCode = $LASTEXITCODE
}
finally {
Pop-Location
}
exit $exitCode