Skip to content

Windows native sandbox blocks all exec_command: 'permission roots or deny lists changed' #881

Description

@baoyu0

Version / branch / commit

  • zero 0.6.0 (npm @gitlawb/zero@0.6.0, win32-x64 binary)
  • Also present on main @ 7f39a63

OS and environment

  • Windows 11 (virtualized sandbox VM), PowerShell 5.1, elevated (Administrator)
  • Native backend: windows-restricted-token (zero sandbox setup completed successfully from an elevated terminal)
  • Go 1.26.5, Node 24.19

Steps to reproduce

  1. Install @gitlawb/zero@0.6.0 and run zero sandbox setup from an elevated terminal. It prints Windows sandbox setup complete.

  2. Run zero doctor from the same directory — sandbox.backend is [pass] (the setup marker validates for the cwd workspace root).

  3. In any small project directory, run:

    zero exec --output-format stream-json --max-turns 10 "Run 'go test ./...' and report the result."
  4. The agent's exec_command tool call aborts before the command executes.

Expected behavior

exec_command should run inside the native Windows restricted-token sandbox (as zero doctor suggests the backend is ready), just as write_file/read_file/edit_file work.

Actual behavior

Every exec_command aborts immediately with:

zero-windows-command-runner.exe: windows sandbox setup is out of date: permission roots or deny lists changed

The run ends with status: incomplete. File tools work fine — only shell execution is blocked.

Root cause (traced on main @ 7f39a63)

  1. internal/sandbox/runner.goBuildCommandPlan builds the profile and then calls permissionProfileWithRuntime(profile, runtimeState) (line ~189).
  2. internal/sandbox/runtime_state.gopermissionProfileWithRuntime appends the per-workspace sandbox runtime root (<LocalAppData>/zero/runtime/v1/<sha256(workspaceRoot)[:8]>) as an extra FileSystem.WriteRoots entry when it isn't already present.
  3. internal/sandbox/windows_command_runner_windows.go (restricted-token tier) validates the stored setup marker using the command's profile: ValidateWindowsSandboxSetupMarker(WindowsSandboxSetupConfigFromCommand(config)).
  4. But zero sandbox setup (internal/cli/sandbox.gorunSandboxSetup) writes the marker via WriteWindowsSandboxSetupMarker from a profile built without the runtime root.
  5. internal/sandbox/windows_setup.goValidateWindowsSandboxSetupMarker compares ACLPlanHash/ACLPlanEntries of the stored marker (no runtime root) against the freshly computed plan from the command profile (with runtime root) → permanent mismatch → permission roots or deny lists changed.

Evidence

  • The runtime root appears after the first exec attempt: C:\Users\<user>\AppData\Local\zero\runtime\v1\55c03089a6535cfb, where 55c03089 = first 8 hex chars of sha256("<workspace>\zero-demo").
  • The stored marker's aclPlanEntries is stable for a given workspace (e.g., 5 for a workspace-only profile), while the command-time plan adds the runtime-root entries → counts/hashes never agree.
  • zero doctor reports the backend as [pass] because doctor builds its profile the same way as setup (without the runtime root), so the two sides of the validation disagree.

Suggested fix direction

Make the elevated Windows setup include the sandbox runtime root in the profile used both for applying ACLs and for writing the setup marker — i.e. prepare the runtime and apply permissionProfileWithRuntime before BuildWindowsACLPlan / WriteWindowsSandboxSetupMarker in the setup path (runWindowsSandboxSetup / runSandboxSetup), so the command-time profile matches the marker.

Relevant logs

[zero] zero-windows-command-runner.exe: windows sandbox setup is out of date: permission roots or deny lists changed

(zero doctor from the same directory: Overall: pass, sandbox.backend: [pass].)

Metadata

Metadata

Assignees

No one assigned

    Labels

    issue-approvedReviewed and approved by the core team; community PRs may implement this issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions