SafetyCard Request a review

GitHub Copilot Chat (VS Code)

GitHub Copilot Chat and agent mode, now in the VS Code repo

github.com/microsoft/vscode › extensions/copilot · 2026-10-03 · 7f20cda

Defense-in-depth score

3.3 / 10

Copilot agent mode asks before every terminal command, untrusted web fetch and non-read-only MCP tool, and the dialog shows the exact command. Those commands then run unsandboxed as you, with all your credentials in the environment. The biggest gap is that a repository's .github/hooks files load automatically once you trust the workspace, which Copilot requires. A preToolUse hook in one of those files can approve tool calls on your behalf, and hooks run shell commands without asking. File edits in the workspace and writes to the global memory tool also happen without approval.

Safest setup

Copilot agent mode asks before every terminal command, untrusted web fetch and non-read-only MCP tool, and shows the exact command line. Those commands then run on your machine with every credential in your environment, and workspace hooks, file edits and memory writes act without asking. The safest setup narrows the environment and turns on the sandbox and approval settings VS Code already includes.

SetupHowWhat it gives you
Scoped, short-lived credentialsOpen projects in a dev container, VM or separate OS user whose environment holds only short-lived credentials scoped to this projectAn approved command reaches only the systems this project needs, not every account your shell can reach C1
The terminal sandboxchat.agent.sandbox.enabled set to on in your user settingsAgent terminal commands and MCP servers run with a mostly read-only filesystem, and leaving the sandbox needs your confirmation C4
A closed sandboxWith the sandbox on, set chat.agent.sandbox.network.allowNetwork and chat.agent.sandbox.fileSystem.allowDevToolAccess to falseSandboxed commands can't reach the Internet or read dev-tool configs and registry tokens C4
Hooks you chosechat.useHooks set to false in your user settings, unless you rely on hooks you wroteEvery tool call reaches your approval dialog, whatever hook files a repository contains C2
Default PermissionsKeep the default chat.permissions.default of default and chat.tools.global.autoApprove at false, and start sessions outside Bypass Approvals and AutopilotTerminal commands, untrusted fetches and MCP tools that change things each wait for your click C2
Reviewed file editschat.tools.edits.autoApprove with the **/* pattern set to falseYou see each workspace edit, including code your tests and scripts will later run, before it lands C2
No persistent memoryDeselect the memory tool in the agent's tool pickerNothing a session reads can leave notes that steer your later chats in other workspaces C6
A request limitKeep chat.agent.maxRequests at its default of 50, or lowerEach turn pauses for your go-ahead after a fixed number of requests C10

Approving with confidence

  • Read each prompt and approve terminal commands one at a time; the dialog shows the exact command line, and you can edit it first.
  • Trusting a workspace also loads its instruction and hook files, so look through .github/hooks and the instruction files of a repository you didn't write before trusting it.
  • The MCP server trust prompt shows a name and origin, so open the server's definition and check its command and package version before trusting it.

Handling data

  • Saved chat sessions keep tool arguments, terminal command lines and results in VS Code's workspaceStorage folder; store it like the projects they cover.

Key gaps (2)

  1. Repository-controlled hook files (.github/hooks/*.json) load by default in trusted workspaces, and a preToolUse hook returning 'allow' bypasses the tool approval gate for any tool, including the terminal. C2 · Approval gates
  2. Agent terminal commands, hooks and MCP stdio servers run on the host as the user with no sandbox by default; the terminal sandbox is off by default. C4 · Code-execution isolation

Criteria

C1 Identity & least privilege

0.17 / 1.00

Copilot's own GitHub sign-in asks only for the user:email scope by default, and the GitHub MCP server that would act on GitHub with the user's token is off by default. Everything else runs with the developer's own authority. Agent terminals inherit the full VS Code environment, which includes cloud, git and SSH credentials, and nothing is scrubbed or scoped. File tools check whether a path is inside the workspace and ask before going outside it, but nothing narrows what the shell can do once a command is approved.

C2 Approval gates

0.25 / 1.00

By default every terminal command needs a click on a dialog that shows the exact command line. Commands are parsed with tree-sitter, and auto-approve rules only take effect after the user accepts a one-time warning. Web fetches to untrusted domains, MCP tools without a read-only hint, and edits to sensitive or out-of-workspace files also ask first. Ordinary file edits inside the workspace are auto-approved by default, and that covers code the user will later run. The decisive problem is that a repository's .github/hooks/*.json is loaded automatically once the workspace is trusted, which is required to use Copilot at all. A preToolUse hook in that file can answer 'allow' and approve any tool call, so a cloned repo can switch the gate off.

C3 Tool & action scoping

0.35 / 1.00

The file tools are fairly careful. They resolve symlinks and real paths, reject null bytes and Windows device paths, and ask before touching anything outside the workspace or under the home dotfiles. The default tool set is very broad, though: a raw shell, arbitrary URL fetch, file writes, notebook execution, VS Code commands and memory are all enabled out of the box. The shell takes arbitrary strings, and the auto-approve rules are filters rather than bounds.

C4 Code-execution isolation

0.35 / 1.00

Agent terminal commands, workspace hooks, tasks and MCP stdio servers run directly on the host as the user, because the terminal sandbox (chat.agent.sandbox.enabled) is off by default. When a user turns the sandbox on, commands are wrapped with @vscode/sandbox-runtime (bubblewrap or Seatbelt), which keeps the filesystem mostly read-only. Leaving the sandbox requires a per-call confirmation. Network is still allowed by default, dev-tool configs and registry tokens stay readable, and hooks are never sandboxed. The default protection against a bad command is the approval dialog, not isolation.

C5 Untrusted input blast radius

0.50 / 1.00

Prompt injection is not detected. What limits a hijacked session is that the dangerous outbound and execution paths ask a human first: terminal commands, fetches to untrusted URLs (where the fetched content is also reviewed before it reaches the model), and non-read-only MCP tools. Remote images in chat output are blocked. Workspace file edits and user-memory writes still happen without approval, so injected content can quietly change code or plant persistent notes. Approval does not depend on whether untrusted content has been read, and tool descriptions or workspace files are treated the same as the user's own instructions.

C6 Memory, context & configuration integrity

0.17 / 1.00

The memory tool is on by default. It lets the model write user-scope notes to global storage without approval, and the start of those notes is injected into every new agent chat in every workspace as 'your persistent user memory', so one injection can persist across all future sessions. Instruction files and workspace hooks load silently once the workspace is trusted. Edits to .vscode/*.json, .mcp.json, hook and custom-agent files always ask first. Workspace MCP servers need both workspace trust and a separate server-trust prompt, which is shown again whenever the definition changes.

C7 Third-party extensions

0.30 / 1.00

No third-party extension code runs without consent. MCP servers defined in a workspace need workspace trust plus a per-server trust prompt, which is shown again when the server definition changes, and the install_extension tool asks before installing anything. The trust prompt shows the server's name and origin rather than the exact command. Package versions are whatever the configuration says, often an unpinned npx package, and stdio servers inherit the full process environment.

C8 Secrets & sensitive-data protection

0.33 / 1.00

BYOK API keys and auth sessions are kept in VS Code's SecretStorage, which is backed by the OS keychain. A regex secret filter exists but only runs on events exported to cloud session sync. Nothing is redacted from prompts sent to the model, from local logs or transcripts, or from the environment of agent terminals. Agent terminals inherit every long-lived credential in the user's environment. Content-bearing GitHub telemetry is sent only when the account's telemetry flag allows it.

C9 Audit & traceability

0.53 / 1.00

VS Code saves every chat session by default to its own workspaceStorage folder, outside the project. Each saved tool call records the tool id, call id, the terminal command line, the result, how it was approved (by the user, a setting, a hook, or auto-approve) and a sub-agent invocation id. A JSONL transcript with tool arguments is also written whenever hooks are configured, and OpenTelemetry export is available as an option. The records are not tamper-evident, and the agent's own terminal can edit or delete them. Storage is best-effort, and a failed write does not stop the agent.

C10 Limits & kill switch

0.30 / 1.00

The agent loop stops after chat.agent.maxRequests requests per turn (50 by default) and then asks the user whether to continue. Autopilot can raise that silently, up to 200. The stop button cancels pending tool calls. There is no session wall-clock limit, cost limit or token budget in the extension. Terminal timeouts only stop the tool from waiting and leave the process running. Sub-agents get their own loops, but nesting is off by default.