Skip to content

Windows: with --sandbox, shell commands can't list or stat directories when the working directory is on a non-system drive #5207

Open

Description

@kuhninator

Summary

On Windows, when Copilot CLI's command sandbox is enabled and the working directory is on a drive other than the system drive (for example D:\), sandboxed shell commands cannot list, stat or change into directories on that drive. Get-ChildItem, Test-Path, cmd /c dir and git repository discovery fail with Access is denied, and the shell does not start in the working directory: Get-Location reports C:\WINDOWS\System32\WindowsPowerShell\v1.0.

Reading a file by its full path still works, and so does .NET [IO.Directory]::GetFiles. The same commands work when the working directory is on C:\, and everything works on D:\ without --sandbox.

Environment

  • Windows 11 Enterprise 26H1, OS build 28000 (x64)
  • GitHub Copilot CLI 1.0.101-0 (installed with WinGet)
  • Windows PowerShell 5.1 as the sandboxed shell
  • Volumes that reproduce it:
    • D: NTFS, fixed disk;
    • E: ReFS Dev Drive (trusted);
    • a freshly created 2 GB NTFS VHDX mounted as T:.
  • Works: C: (NTFS, system drive).
  • No sandbox settings beyond --sandbox.

Steps to reproduce

  1. Create a test folder on a non-system drive:

    New-Item -ItemType Directory D:\sandbox-probe | Out-Null
    Set-Content D:\sandbox-probe\existing.txt 'hello'
    cd D:\sandbox-probe
  2. Run the CLI with the sandbox enabled and ask it to run this probe:

    copilot --sandbox --allow-all --no-ask-user -s -p @'
    Run exactly this PowerShell, once, then print its raw output verbatim:
    $w = 'D:\sandbox-probe'
    "location=$((Get-Location).ProviderPath)"
    try { (Get-ChildItem -LiteralPath $w -ErrorAction Stop).Name } catch { "Get-ChildItem: $($_.Exception.Message)" }
    try { Test-Path -LiteralPath $w -ErrorAction Stop } catch { "Test-Path: $($_.Exception.Message)" }
    cmd /c "dir /b D:\sandbox-probe"
    try { [IO.File]::ReadAllText('D:\sandbox-probe\existing.txt') } catch { "ReadAllText: $($_.Exception.Message)" }
    try { [IO.Directory]::GetFiles($w) } catch { "GetFiles: $($_.Exception.Message)" }
    '@
  3. Run the same command without --sandbox as a control.

  4. Optionally, repeat steps 1–3 with a folder under %LOCALAPPDATA%\Temp on C: (adjust $w).

(Set-Location is left out of the probe because in -p mode it triggers a CLI approval prompt, which is unrelated to the sandbox. In our runs through the Copilot SDK with the same sandbox, Set-Location D:\sandbox-probe also fails with Access is denied.)

Expected

The sandboxed shell starts in the working directory and can list and stat it, as it does on C:. copilot help sandbox says sandboxed commands can access the allowed paths, and the working directory is allowed by default. The sandbox's PowerShell setup is meant to make the working directory's drive enumerable when it isn't the system drive.

Actual

With --sandbox, working directory D:\sandbox-probe:

location=C:\WINDOWS\System32\WindowsPowerShell\v1.0
Get-ChildItem: Access is denied
False
Test-Path: Access is denied
Access is denied.
hello

D:\sandbox-probe\existing.txt

Without --sandbox (control), same folder:

location=D:\sandbox-probe
existing.txt
True
existing.txt
hello

D:\sandbox-probe\existing.txt

With --sandbox, working directory on C:: every probe succeeds, and location is the working directory.

Summary across volumes (sandbox on):

Working directory Get-ChildItem Test-Path cmd dir git status Read by full path .NET GetFiles
C: NTFS (system) OK True OK OK OK OK
D: NTFS Access denied Access denied Access denied "not a git repository" OK OK
E: ReFS Dev Drive Access denied Access denied Access denied "not a git repository" OK OK
T: new NTFS VHDX Access denied Access denied Access denied "not a git repository" OK OK

Diagnostics

  • Engagement: the sandbox reports itself as engaged (process_container backend), and host support reports filesystem enumeration as supported.
  • Policy: the effective sandbox policy includes an enumeration grant for both the system drive and the working directory's drive (for D:, the roots C:\ and D:\), and the working directory is in the read-write paths.
  • Not drive-specific: a freshly created NTFS VHDX fails the same way, so this isn't about one drive's history or permissions. Dev Drive filter policy isn't the cause either, since plain NTFS volumes fail too.
  • ACLs: the volume roots have ordinary default ACLs. One difference: the C:\ root carries an extra capability ACE (S-1-15-3-65536-…) that the other roots lack. Copying that ACE to D:\ did not fix it (since reverted).
  • Filters: fltmc instances shows bindflt attached to C: only, and bfs attached to C: and D:. Attaching bindflt to D: did not fix it (since reverted).
  • Process Monitor: a trace of a failing run showed no ACCESS DENIED result on the test folder. The denial may happen at a layer Process Monitor doesn't observe, such as the sandbox's own brokering. Raw traces are available on request.
  • Partial enumeration: .NET Directory.GetFiles succeeds where Get-ChildItem and cmd dir fail. So enumeration is not blocked outright; some directory-open or metadata queries are denied while others succeed.

Workarounds tried

  • Working directory on C:: works.
  • Adding the C:\ root's capability ACE to D:\ and E:\: no change (reverted).
  • Attaching bindflt to D:: no change (reverted).

Impact

On machines where repos live on a data drive or a Dev Drive (which Windows recommends for development), turning on the sandbox makes the working directory unusable for ordinary shell commands and git, even though the CLI reports the sandbox as engaged. The failure looks like the agent "can't see the repo", not like a sandbox restriction, so it's hard to diagnose.

Suspected component

The Windows process_container sandbox (MXC): the drive-root enumeration grant for a non-system working-directory drive appears not to take effect, or to cover only some directory operations. We have not confirmed the exact denied operation.

Activity

  1. caarlos0 commented on Oct 20, 2026

    @caarlos0
    Member

    Thanks for the detailed report and diagnostics.

    What we confirmed

    • The sandbox policy is correct. It sends an enumeration grant for the system drive root and for the working directory's drive root. This matches your diagnostics.
    • Windows enforces that grant (Process Security Environment 1.1 and bfs.sys) through MXC. The Copilot CLI only builds the policy. We cannot change the enforcement from the CLI.

    Likely cause

    Your failures match open issues in microsoft/mxc:

    [IO.Directory]::GetFiles can succeed where Get-ChildItem and cmd dir fail because it uses a different open.

    Open question

    In microsoft/mxc#1461 there is no enumeration grant. In your case, the grant is present on D:\ and the failures remain. So either the grant does not cover root metadata queries on build 28000, or it does not take effect. We have not reproduced this on Windows yet.

    Useful next data

    • A run of the probe with --sandbox that shows the exact failing call (an NtOpenFile trace, or the Process Monitor trace you offered).
    • Whether adding D:\ to the sandbox's read-only paths changes the result. This lets commands read every file on D:\, so use it only for a test.

    Until this is fixed upstream, a working directory on C: is the reliable workaround.

  2. added
    area:permissionsTool approval, security boundaries, sandbox mode, and directory restrictions
    area:platform-windowsWindows-specific: PowerShell, cmd, Git Bash, WSL, Windows Terminal
    and removed on Oct 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:permissionsTool approval, security boundaries, sandbox mode, and directory restrictionsarea:platform-windowsWindows-specific: PowerShell, cmd, Git Bash, WSL, Windows Terminal

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions