The short answer
In VS Code’s agent mode, chat.tools.terminal.autoApprove decides which terminal commands run without a prompt. Each rule is true (run without asking), false (ask first) or a regular expression between slashes; a compound command runs without asking only if every part matches a true rule and none matches a false rule.1 A false rule asks; it never blocks.1 chat.tools.global.autoApprove removes prompts for every tool in every workspace, and the settings reference describes it as disabling critical security protections.2
VS Code’s own docs say terminal auto-approval is “a best-effort convenience, not a security boundary,” and point to sandboxing, chat.agent.sandbox.enabled, for limits that hold after a command is approved.1
Deedglass
A tool call meets your rules before it runs
Asks to run
DELETE FROM visits;
Deletes every row in visits
Deedglass checks your rules
- Reading dataAllowed
- Deleting a whole table (DROP, TRUNCATE)Never
- Changing or deleting rows without saying which (WHERE)This one
- Other changesWait for a person
The settings that matter
| Setting | Default | What it does |
|---|---|---|
chat.tools.terminal.enableAutoApprove |
true |
Turns rule-based terminal auto-approval on or off; off means every command asks2 |
chat.tools.terminal.autoApprove |
rm, rmdir, del, kill, curl, wget, eval, chmod, chown and a PowerShell Remove-Item pattern set to false2 |
Per-command rules |
chat.tools.global.autoApprove |
false |
Approves all tools, everywhere2 |
chat.tools.urls.autoApprove |
Separate approval for contacting a URL and for adding its content to the chat1 | |
chat.tools.edits.autoApprove |
{} |
Glob patterns for files whose edits need approval2 |
chat.agent.sandbox.enabled |
off |
Restricts the files and network agent terminal commands can reach2 |
When a prompt does appear, you can approve a single use, or for the session, the workspace or all future invocations.1 Each wider choice is a standing rule. Those clicks add up.
How terminal rules combine
From the docs:1
- Each subcommand of a compound command is checked on its own, by default.
- The compound command runs without asking only if every subcommand matches a
truerule and none matches afalserule. - A
falserule always wins overtrue. - Object syntax with
matchCommandLinechecks the full command line instead of each part. - Common read-only commands run without asking by default; risky ones such as
rmanddelask.
Worked examples
Take this rule set:
Code Data in JSON, the format software uses to pass records and settings.
{
"chat.tools.terminal.autoApprove": {
"npm test": true,
"/^git (status|diff|log)\\b/": true,
"rm": false,
"/prisma migrate reset/": false
}
}
Applying the documented rules:1
| Command | Result | Why |
|---|---|---|
npm test |
Runs | Matches a true rule |
git status && git diff |
Runs | Both parts match true |
npm test && rm -rf dist |
Asks | rm matches false |
npx prisma migrate reset --force |
Asks | Matches the false regex |
psql $DATABASE_URL -c "DROP TABLE users" |
Asks | No true rule matches |
bash scripts/cleanup.sh (which runs rm -rf /data) |
Asks unless bash or the script is allowed |
The rule sees bash scripts/cleanup.sh, not what’s inside |
The last row is the general limit. Rules read the command line, not what it does. If anyone adds "bash": true to save prompts, every script becomes a way past the rm rule.
Why rules aren’t a boundary
The docs say it plainly: terminal auto-approval is best-effort, not a security boundary.1 Three reasons, visible in the table above:
falseasks, it doesn’t block. A tired person approves.- Indirection. Scripts,
eval-like constructs and package scripts hide the real command. (evalis on the default ask list for that reason.)2 - Standing approvals. “Allow for this workspace” and “always” turn a one-time judgment into a rule nobody revisits.
The sandbox is different in kind: it restricts what agent terminal commands can reach even after they’re approved.1 Its default is off.2
Hooks are a third option, with their own catch: VS Code’s hooks docs say tool names and input schemas differ between harnesses and don’t name the terminal tool or its arguments, which makes a portable shell guard hard to write.3 For Copilot’s cloud agent and CLI, see our preToolUse hooks post.
A settings block we would start from
Code Data in JSON, the format software uses to pass records and settings.
{
"chat.agent.sandbox.enabled": "on",
"chat.tools.global.autoApprove": false,
"chat.tools.terminal.enableAutoApprove": true,
"chat.tools.terminal.autoApprove": {
"npm test": true,
"npm run lint": true,
"/^git (status|diff|log|show)\\b/": true,
"/prisma (migrate reset|db push)/": false,
"/\\b(dropdb|psql|mysql)\\b/": false
},
"chat.tools.edits.autoApprove": {
"**/.env*": false,
"**/.github/**": false
}
}
The setting names and value shapes are from VS Code’s docs;12 the edit patterns use the documented glob form, so check how your version treats false there before relying on it. The idea is narrow true rules for the commands you run all day, explicit asks for database tools, the sandbox on, and nothing global.
Audit what you’ve already approved
Before changing anything, look at what’s there. Open your user settings.json and the workspace .vscode/settings.json and search for autoApprove. For each true rule, ask two questions:
- Could this command change something outside the project?
git push, package publishing, cloud CLIs and database clients all can. - Could it run something else?
bash,sh,node,python,npxandmakerun whatever they’re given.
Anything that answers yes to either should go back to asking. The commands worth auto-approving are the boring ones: tests, linters and read-only git.
For teams
- Keep global auto-approve off everywhere. If you manage VS Code settings centrally, set it there, so one developer’s convenience doesn’t become the team’s default.
- Review workspace-level approvals. “Allow for this workspace” can be committed or shared; read them like code.
- Give the agent narrow credentials. No terminal rule protects a production database the agent can reach with an owner’s password. Our Claude Code sandbox post makes the same point for another client.
A human-in-the-loop approval only helps if the person sees the real command and has a reason to say no.
To see which destructive commands an agent configured on your machine could run without a prompt, paste the config into the check page or run npx deedglass scan (how the grade works); to try tool-call rules in your browser, open the playground.
Questions people ask
Does a false autoApprove rule block a command in VS Code?
No. It requires approval; it does not block.1
Is chat.tools.global.autoApprove safe?
The settings reference says it disables critical security protections; it’s off by default.2
Does VS Code sandbox agent terminal commands?
Only if you enable chat.agent.sandbox.enabled; the default is off.2
Written with AI assistance and checked against our claims register.