Describe the bug
In ACP mode (copilot --acp), the local sandbox is never applied, even when the CLI is started
with --sandbox --experimental and settings.json has sandbox.enabled: true and
allowBypass: false. A shell write to a path in sandbox.userPolicy.filesystem.readonlyPaths
succeeds. The same COPILOT_HOME, policy, and prompt in -p mode are blocked by the OS sandbox.
Evidence from the two sessions:
|
copilot -p ... --sandbox |
copilot --acp --sandbox |
| Write to read-only path |
Blocked: Access to the path '...\tests\Locked.txt' is denied. |
Succeeded, exit 0 |
events.jsonl tool telemetry |
sandboxApplied:"true", sandboxed:true |
sandboxApplied:"false" |
| Debug log, shell diagnostics |
n/a |
sdk shell exit {... "sandbox":false ...} |
| Debug log, telemetry |
cli_sandbox:"true", config_sandbox_enabled:"true" |
No cli_sandbox or config_sandbox_* fields |
session/new exposes the config options mode, model, reasoning_effort, agent and
allow_all. None of them is a sandbox option, so an ACP client has no other way to enable it.
Affected version
GitHub Copilot CLI 1.0.94-5.
Steps to reproduce the behavior
-
Create a git repo with a file tests\Locked.txt that contains original.
-
Create an empty COPILOT_HOME folder, copy your config.json into it (for auth), and add
this settings.json, using the absolute path of the repo's tests folder:
{
"sandbox": {
"enabled": true,
"allowBypass": false,
"userPolicy": {
"filesystem": { "readonlyPaths": ["C:\\path\\to\\repo\\tests"] },
"network": { "allowOutbound": true, "allowLocalNetwork": true }
}
}
}
-
Control (-p): from the repo root, with COPILOT_HOME set to that folder, run:
copilot -p "Use only the powershell tool. Run exactly: Set-Content tests\Locked.txt changed then report the exit code and any error verbatim. Do not retry." --sandbox --experimental --allow-all-tools --log-level debug
Result: exit code 1, Access to the path '...\tests\Locked.txt' is denied. The file still
contains original.
-
ACP: with the same COPILOT_HOME and working directory, start
copilot --acp --sandbox --experimental --log-level debug from an ACP client. Send
initialize, then session/new, then a session/prompt with the same text. Approve the
shell permission request with allow_once.
-
Result: the command exits 0, and tests\Locked.txt now contains changed.
-
Compare COPILOT_HOME\session-state\<id>\events.jsonl for the two sessions: -p records
sandboxApplied:"true", while ACP records sandboxApplied:"false".
Expected behavior
ACP sessions apply the local sandbox in the same way as interactive and -p sessions when
--sandbox is passed or sandbox.enabled is true. If that isn't intended, ACP should expose
the sandbox as a session/new config option, or fail clearly at startup instead of running
unsandboxed.
Additional context
- OS: Windows 11, build 26300.9705, x64
- Terminal / shell: Windows Terminal, PowerShell 7. The ACP client is a small .NET app that
talks JSON-RPC over stdio.
--log-file isn't accepted by 1.0.94-5 (unexpected argument '--log-file'), so the debug
logs come from COPILOT_HOME\logs. I can attach both logs if they're useful.
- Why it matters: ACP is the mode that lets an orchestrator stream progress, answer permission
requests, cancel, and re-prompt in a single long-lived process. Without the sandbox there,
the orchestrator has to choose between steering (ACP) and OS-enforced write limits (-p).
- Related:
Describe the bug
In ACP mode (
copilot --acp), the local sandbox is never applied, even when the CLI is startedwith
--sandbox --experimentalandsettings.jsonhassandbox.enabled: trueandallowBypass: false. A shell write to a path insandbox.userPolicy.filesystem.readonlyPathssucceeds. The same
COPILOT_HOME, policy, and prompt in-pmode are blocked by the OS sandbox.Evidence from the two sessions:
copilot -p ... --sandboxcopilot --acp --sandboxAccess to the path '...\tests\Locked.txt' is denied.events.jsonltool telemetrysandboxApplied:"true",sandboxed:truesandboxApplied:"false"sdk shell exit {... "sandbox":false ...}cli_sandbox:"true",config_sandbox_enabled:"true"cli_sandboxorconfig_sandbox_*fieldssession/newexposes the config optionsmode,model,reasoning_effort,agentandallow_all. None of them is a sandbox option, so an ACP client has no other way to enable it.Affected version
Steps to reproduce the behavior
Create a git repo with a file
tests\Locked.txtthat containsoriginal.Create an empty
COPILOT_HOMEfolder, copy yourconfig.jsoninto it (for auth), and addthis
settings.json, using the absolute path of the repo'stestsfolder:{ "sandbox": { "enabled": true, "allowBypass": false, "userPolicy": { "filesystem": { "readonlyPaths": ["C:\\path\\to\\repo\\tests"] }, "network": { "allowOutbound": true, "allowLocalNetwork": true } } } }Control (
-p): from the repo root, withCOPILOT_HOMEset to that folder, run:Result: exit code 1,
Access to the path '...\tests\Locked.txt' is denied.The file stillcontains
original.ACP: with the same
COPILOT_HOMEand working directory, startcopilot --acp --sandbox --experimental --log-level debugfrom an ACP client. Sendinitialize, thensession/new, then asession/promptwith the same text. Approve theshell permission request with
allow_once.Result: the command exits 0, and
tests\Locked.txtnow containschanged.Compare
COPILOT_HOME\session-state\<id>\events.jsonlfor the two sessions:-precordssandboxApplied:"true", while ACP recordssandboxApplied:"false".Expected behavior
ACP sessions apply the local sandbox in the same way as interactive and
-psessions when--sandboxis passed orsandbox.enabledis true. If that isn't intended, ACP should exposethe sandbox as a
session/newconfig option, or fail clearly at startup instead of runningunsandboxed.
Additional context
talks JSON-RPC over stdio.
--log-fileisn't accepted by 1.0.94-5 (unexpected argument '--log-file'), so the debuglogs come from
COPILOT_HOME\logs. I can attach both logs if they're useful.requests, cancel, and re-prompt in a single long-lived process. Without the sandbox there,
the orchestrator has to choose between steering (ACP) and OS-enforced write limits (
-p).skillDirectoriessetting fromsettings.jsonis not honored in ACP mode (copilot --acp) #4700 (settings.jsonskillDirectoriesisn't honored in ACP mode). This might be the sameroot cause: settings not reaching ACP sessions.
session/newexposes only a few config options).