Windsurf Cascade auto-execution: Turbo mode, allow lists, deny lists and hooks

Cascade can run terminal commands on its own at four levels, from Disabled to Turbo. The lists that steer it match by prefix, and a deny entry means ask, not block. Here is how each piece behaves.

The short answer

Windsurf’s Cascade agent has four auto-execution levels for terminal commands: Disabled, Allowlist Only, Auto and Turbo.1 Disabled asks before every command. Allowlist Only runs listed commands and asks for the rest. Auto lets the model judge which commands are safe, and only for messages sent with premium models. Turbo runs every command except those on your deny list.1 A deny-list match doesn’t block a command; it makes Cascade ask.1 If you need a command to never run, write a pre_run_command hook that exits with code 2.2

Every MCP tool call goes through your rules first. Here a delete that doesn’t say which rows is stopped before it reaches the database. These are the rules deedglass init starts with; the call is made up.

A note on the name

Windsurf’s documentation now lives on docs.devin.ai under the name Devin Desktop, and the old Windsurf docs URLs redirect there.1 The settings described here apply to the Cascade agent. The newer Devin Local agent in the same app replaces these levels with its own allow, ask and deny rules.1 If your settings panel looks different from this post, check which agent you’re using.

The four levels

You choose a level in the settings panel at the bottom right of the editor.1

Level What runs without asking Who decides
Disabled Nothing You, every time
Allowlist Only Commands matching your allow list The list
Auto Commands the model judges safe The model (premium models only)
Turbo Everything not on the deny list Nobody, unless the deny list matches

Source: the terminal docs.1

The first two are deterministic: the same command gets the same answer. Auto is a judgment call by a model, which is the same design Cursor uses for its Auto-review classifier and which Cursor itself says is not a security boundary.4 VS Code’s docs make the same point about their own terminal auto-approval: “a best-effort convenience, not a security boundary.”3 None of these vendors is wrong; a model reviewing commands catches a lot. It just isn’t something to rely on alone.

Turbo is the one to be careful with. It inverts the default: instead of listing what may run, you list what may not, and anything you forgot runs. Its safety is exactly as good as your deny list’s coverage of every destructive command, alias and script on your machine.

How allow and deny entries match

Entries are managed from the command card Cascade shows when it wants to run something.1

Action on the card What gets saved What it matches
Allowlist → Allow The exact command Only that exact command
Allowlist → Prefix The base command plus * Every command starting with the same tokens
Deny The base command Every command starting with the base command

Source: the terminal docs.1

So git * on the allow list auto-runs git add -A, as the docs say, and also git reset --hard, git clean -fdx and git push --force.1 The Prefix button is convenient precisely because it is broad. The Allow button is narrow: it approves the command you’re looking at and nothing else.

Deny works on the base command. Denying rm covers rm index.py and rm -rf /.1 What it can’t see is a destructive action under a different name: a make clean target, an npm script, a Python one-liner that deletes a directory, or a database client running DROP TABLE. List matching reads the command’s text, not what the command does.

Practical rules:

  1. Prefer Allow over Prefix for anything that writes.
  2. Use Prefix only for read-only tools: ls *, cat *, rg *.
  3. Deny the obvious bases: rm, mv, git, psql, mysql, mongosh, dropdb, docker, kubectl, terraform, aws, gcloud. Denying git costs you a prompt for git status; that’s the right trade in Turbo.
  4. Review the lists monthly. Every Prefix click is a standing approval.

Team limits

Teams and Enterprise admins have two levers in the Admin Portal.1

A maximum level. If the admin sets the maximum to Auto, members can pick Disabled, Allowlist Only or Auto, but not Turbo.1 For most teams, capping at Allowlist Only or Auto is the single most useful setting.

Team-wide lists. Team allow and deny lists merge with each person’s lists. A command matching either the team or the user allow list auto-runs, unless a deny list matches; a deny match at either level means approval is required, and deny takes precedence.1

The merge has a sharp edge. Because allow lists add up, a member’s personal git * entry still auto-runs git push even if the team never allowed it, unless the team denies it. If there are commands no one should run unattended, put them on the team deny list rather than leaving them off the team allow list.

Hooks: the one hard block

Cascade Hooks run your script at fixed points: before and after reading code, writing code, running a command, using an MCP tool, and before a prompt.2 They load from three places and all of them run, in this order:

Level Location
System /Library/Application Support/Devin/hooks.json (macOS), /etc/devin/hooks.json (Linux), with the old Windsurf paths as fallback
User ~/.codeium/windsurf/hooks.json
Workspace .devin/hooks.json (or the legacy .windsurf/hooks.json)

Source: the Cascade Hooks docs.2

A pre_run_command hook receives JSON with tool_info.command_line and cwd.2

Code Data in JSON, the format software uses to pass records and settings.

{
  "agent_action_name": "pre_run_command",
  "tool_info": {
    "command_line": "psql $DATABASE_URL -c 'DELETE FROM orders'",
    "cwd": "/Users/you/project"
  }
}

Exit code 2 blocks the command and shows your stderr to the agent; exit 0 lets it run.2 This works at every level, Turbo included, which makes it the only control in this post that says no rather than ask.

Three limits to plan for:

  • Any other exit code lets the command run. A crash, a missing interpreter or a syntax error in your script fails open.2 Test the hook with a known-bad command after every change.
  • Hooks don’t run in Restricted Mode. If a workspace is opened in Restricted Mode, hooks don’t load.2
  • A workspace hook file is part of the repo. Anyone who can change .devin/hooks.json can change your policy. Put the rules that matter at the system level, which an MDM tool can manage.

A hook also reads the command text, like the lists. It is better than a list because it can parse the whole line, follow && and ;, and look inside -c strings, but it still can’t know what a script it calls will do.

A setup we would start from

  1. Level: Allowlist Only for daily work. Auto if you want fewer prompts and accept a model’s judgment. Turbo only in a throwaway environment.
  2. Allow list: exact commands for builds and tests; Prefix entries only for read-only tools.
  3. Deny list: destructive bases and every database and cloud CLI you have installed.
  4. Admins: cap the maximum level and keep a team deny list.
  5. Hook: a system-level pre_run_command hook that exits 2 for commands that must never run unattended, such as DROP, TRUNCATE and DELETE without WHERE through any database client.
  6. Credentials: keep production database URLs out of the shell environment Cascade’s terminal inherits. The dedicated terminal loads your .zshrc or .bashrc, so anything exported there is in reach.1

What none of this covers

Levels, lists and hooks all act before a command runs. Once an allowed command reaches a database, none of them can say what it changed. If Cascade reports “updated the stale rows” after a psql call, the report is the agent’s account, not a record.

Two things help here. First, give the agent a database role that can’t do the damage you fear, so an allowed command is a limited command. Second, check the effect: compare what the agent said with what the database recorded. Our MCP config paths post shows where Windsurf keeps its MCP servers, which is where an agent’s database access usually comes from. To see an approval and a read-back on a real database in your browser, open the playground. To grade what agents on your machine can reach, including Windsurf’s MCP config, run npx deedglass scan (the grade, explained).

Questions people ask

Is Turbo mode safe?

It runs every command that isn’t on your deny list.1 It is as safe as the machine it runs on: fine in a disposable container with no credentials, risky on a laptop with production access.

Why did a denied command still run?

A deny entry makes Cascade ask; it doesn’t block.1 If you clicked approve, it ran. For a hard block, use a hook that exits 2.2

Does Auto mode work with every model?

No. The docs say Auto is only available for messages sent with premium models.1

Written with AI assistance and checked against our claims register.

The takeaway

In Windsurf Turbo, every command runs unless it's on the deny list, and a deny match only asks; a pre_run_command hook exiting 2 is the one hard block.

Read nextCursor auto-run settings: the allowlist, permissions.json and sandbox.json, explained Try it: install in 7 s

Related on this site

More posts

Sources

  1. 1Devin Desktop (Windsurf) docs: Terminal · docs.devin.ai · checked 27 October 2026
  2. 2Devin Desktop (Windsurf) docs: Cascade Hooks · docs.devin.ai · checked 27 October 2026
  3. 3VS Code docs: approvals and permissions · code.visualstudio.com · checked 26 October 2026
  4. 4Cursor docs: Run Modes · cursor.com · checked 27 October 2026

Published 27 October 2026, sources last checked 27 October 2026. If something here is out of date, write to hello@deedglass.com.

Try it on your own setup

npx deedglass scan

Grades only your own setup. Nothing is uploaded.

Pricing