The new boundary needs a local acceptance record
GitHub announced local sandboxing for the Copilot app on September 23, 2026, in public preview. Project settings constrain files, networks, and credentials in local repository and working-tree sessions. Remote hosts and cloud sessions are excluded; Copilot CLI has separate settings. Enterprise policy may narrow what a project requests.
The practical question is whether your exact workstation configuration enforces the boundary you intend. The protocol below is a proposed acceptance test, not a report of tests we ran. Use a disposable project and record observable operations. An agent saying that it cannot access a file is weaker evidence than an attempted read with a recorded error and an independently checked fixture.
Prepare four folders and two endpoints
Create a workspace containing a small text file, an external writable fixture folder, an external read-only fixture folder, and a denied child inside the writable fixture. Put distinct synthetic markers in each. Use names such as workspace-marker, shared-marker, and denied-marker; never copy a real secret to make the test realistic. Save original file contents or hashes outside the test session so you can check attempted modifications independently.
Prepare an internet endpoint and a local HTTP endpoint you control. Each should return a fixed harmless body and log a unique request ID. Confirm both work from your host before testing. For authentication, use a disposable identity with access to one private fixture repository. Remove alternate token environment variables from the fixture and record authentication configuration without printing secrets. A public repository would make a poor authentication check because a successful read would not establish that credentials were used.
Record app version, OS version, project path, session identifier, start time, requested settings, and known enterprise restrictions. This evidence belongs beside your zero-trust controls for AI agents. It tests a different execution environment from Cursor workers in Vercel Sandbox; do not reuse a cloud isolation result as workstation evidence.
Write the expected result before running a probe
The configuration documentation gives the filesystem contract: workspace/current-directory writes, additional writable or read-only paths, and denied folders. A nested denial overrides an allowed parent. Network access and HTTPS Git/GitHub CLI authentication start enabled. Configure the restrictive fixture explicitly.
Run each operation through the agent's sandboxed tool path. Keep a result column beside this proposed matrix, with the exact command, exit status, error category, timestamp, and evidence link. An intended allow assumes that ordinary host permissions and enterprise policy also permit the operation. A stricter enterprise denial is a policy difference to resolve, not proof that the local setting was ignored.
| Probe and selected policy | Expected outcome | Evidence to retain |
|---|---|---|
| Read and append to the workspace fixture | Allow | Marker returned; append verified independently |
| Read and append in the additional writable folder | Allow | Original marker and changed fixture |
| Read, then append in the additional read-only folder | Read allowed; append denied | Read result, write error, unchanged contents |
| Read and append in the denied child of the writable folder | Deny both, or unsupported-policy startup error on an incapable host | No returned marker; no modified file; shell-start evidence |
| Request controlled internet endpoint with outbound access blocked | Deny connection | Tool error and endpoint log, compared with allowed control |
| Request local endpoint with local access blocked | Deny where supported; qualify Linux spawned-process case below | Caller type, endpoint log and matching allowed control |
| Read private fixture refs over HTTPS with Git credentials disabled | No successful authenticated read through that credential path | Authentication outcome with network held enabled |
| Query private fixture metadata through GitHub CLI with CLI credentials disabled | No successful authenticated query through that credential path | CLI result; matching enabled-credential control |
For every blocked network or authentication row, repeat the same read-only operation in a newly started session with only the relevant setting changed. Keep endpoint, identity, and fixture constant. If the allowed control fails too, label the pair inconclusive. DNS failure, an unavailable server, expired authentication, or repository permissions must not be scored as a sandbox success. If a supposedly blocked operation succeeds, stop the acceptance run and inspect alternate authentication paths or session age before widening the claim.
Test policy changes across three session states
GitHub's announcement says sandboxing starts off. Enabling the project default affects new sessions, while policy edits require a new or restarted session. In an active session, /sandbox on changes that session without changing the project default. A host unable to enforce the requested policy should fail the shell rather than run unsandboxed.
Start session A in the disposable project with sandboxing off. Enable the project default, then start session B. Retain the state indicators from both sessions. In A, invoke /sandbox on and check its state again. Compare B's newly inherited configuration with A's explicit session change; a screenshot of the project switch alone cannot establish what A is doing.
Next, use an allowed fixture read in B as a baseline. Add that fixture folder to the denied list in project settings. Repeat the read in the still-running B, then start session C and repeat it there. Finally restart B with /restart-session and repeat once more. The documented restart keeps history. Your record should distinguish the old policy, the new-session policy, and the restarted-session policy rather than collapsing all three into one result.
| Transition under test | Expected policy relationship | Acceptance evidence |
|---|---|---|
| Project default enabled while A runs | A unchanged; new B inherits default | Session IDs and state before/after |
| Active A receives /sandbox on | A sandbox enabled; project default unchanged | A state plus project setting capture |
| Fixture denied while B runs | B retains previous policy | Same fixture operation in B |
| New C starts; B later restarts | Each receives updated requested policy, subject to enforcement | Denied read or explicit unsupported-policy result |
Preserve platform limits and exception decisions
GitHub documents two significant qualifications: Windows may reject an unsupported denied-path policy; Linux cannot independently restrict local networking for spawned processes, although in-process operations remain covered. The app may also offer an outside-sandbox exception, subject to policy. These qualifications are part of the documented boundary.
On Linux, split your local-network row by caller: a shell process and an in-process request are different cases. Mark independent local-network restriction for spawned processes as unsupported rather than awarding a pass. If that separation is a requirement for your workflow, the acceptance decision remains no-go for that configuration until you have another tested control.
For an unsupported Windows policy, record the shell error and verify that the attempted fixture write did not occur. That is evidence of rejection, not evidence of a usable restrictive session. Resolve support before accepting the workflow. During the matrix, cancel any outside-sandbox offer and record it separately. Approving the exception would change what the test measures.
Accept one configuration, with explicit gaps
Use four result labels: pass, fail, inconclusive, and unsupported. Require both the successful allowed control and the intended denied operation for each supported restriction. Keep credential tests narrowly tied to the tested HTTPS Git or CLI path; they do not establish that every possible secret source is inaccessible. Re-run affected rows after an app update, OS change, enterprise-policy change, or credential integration change.
Your final record should name the configuration approved, the rows exercised, exceptions declined, unresolved limitations, and the reviewer. A blocked shell, a stale session, and an enforced restriction are three different outcomes. Preserving that distinction makes the sandbox setting useful as an operational control instead of merely a checked box.