News

GitHub Copilot App Adds Local Sandboxing: Verify Files, Network and Credentials

Run a local Copilot sandbox acceptance matrix for file access, network restrictions, credentials, and policy changes across active and new sessions.

2026-09-24

A compact black computer sits inside a glass cube within a larger glass enclosure, beside a stack of file drawers, with cables running out through the glass and brass keys hanging from one cable.
Illustration: each enclosure only counts as a boundary once a denied read, request or login has been recorded against a working control.

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 policyExpected outcomeEvidence to retain
Read and append to the workspace fixtureAllowMarker returned; append verified independently
Read and append in the additional writable folderAllowOriginal marker and changed fixture
Read, then append in the additional read-only folderRead allowed; append deniedRead result, write error, unchanged contents
Read and append in the denied child of the writable folderDeny both, or unsupported-policy startup error on an incapable hostNo returned marker; no modified file; shell-start evidence
Request controlled internet endpoint with outbound access blockedDeny connectionTool error and endpoint log, compared with allowed control
Request local endpoint with local access blockedDeny where supported; qualify Linux spawned-process case belowCaller type, endpoint log and matching allowed control
Read private fixture refs over HTTPS with Git credentials disabledNo successful authenticated read through that credential pathAuthentication outcome with network held enabled
Query private fixture metadata through GitHub CLI with CLI credentials disabledNo successful authenticated query through that credential pathCLI 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 testExpected policy relationshipAcceptance evidence
Project default enabled while A runsA unchanged; new B inherits defaultSession IDs and state before/after
Active A receives /sandbox onA sandbox enabled; project default unchangedA state plus project setting capture
Fixture denied while B runsB retains previous policySame fixture operation in B
New C starts; B later restartsEach receives updated requested policy, subject to enforcementDenied 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.

Sources checked 2026-09-24