What Windsurf typically generates and where the trust boundary is
Like other editor-based tools, Windsurf works inside whatever project you open, so the framework, hosting and database are yours. Its documentation has moved: the Windsurf docs address now redirects to a Devin Desktop documentation site, which describes an AI IDE and mentions Windsurf as a former name. Product names and menu labels may therefore differ from what you see, so check the current documentation for your version.
The current documentation describes four terminal auto-execution levels for the agent. Disabled requires approval for every command. Allowlist only auto-runs commands you approved. Auto leaves the safety judgment to the agent and still asks about risky commands, on premium models only. Turbo runs everything except commands on the deny list. It also describes allow and deny lists, where a command matching both requires approval, and administrator controls on team plans that cap the maximum level. Verify setting names in your build.
The boundary here has two sides. Code the agent writes is untrusted until you read and test it. And anything you pre-approve for execution widens the damage from a mistake or from instructions hidden in a file or web page the agent reads. The most permissive level is convenient and removes the pause where you would notice a bad command.
The review checklist
| Area | What to verify | How to test on your own project | Pass condition |
|---|---|---|---|
| Auto-execution level | The level matches how much you trust the current project and environment. | Open the agent's terminal settings and read the current level. | Not on the fully automatic level unless the environment is disposable. |
| Allow list | Only narrow, read-only commands run without asking. | Read every allowlist entry, including short ones such as a bare command name. | No entry lets the agent delete, push, deploy or reach a database unprompted. |
| Deny list | Destructive commands are blocked from auto-running. | Read the deny list for deletion, force push and database commands. | Destructive commands always require your approval. |
| MCP servers | Each connected server is chosen, understood and minimally credentialed. | Review the MCP configuration file and each token or command listed. | You can explain every server and none holds excess privilege. |
| Memories and rules | Saved rules and memories contain no secrets or review-skipping instructions. | Read the workspace and global rules and any saved memories. | Only conventions, no credentials. |
| Secrets in the repo | No key was written into files, tests or examples. | Run the pattern and history searches in the commands section. | No hits, or every hit has been rotated. |
| Diff review | Each change was read, especially auth, data and configuration files. | Review by file with git before staging. | You can explain what each changed file does and why. |
| Running app | Authorization and input handling hold up when called directly. | Use curl unauthenticated and as the wrong user against each route. | Rejections, and no cross-user data. |
Commands and queries to run
Run these in your own repository after a Cascade session. They show what changed, what dependencies arrived and whether any secret was written.
The final command lists tracked environment files. No output, apart from an example file with placeholders, is the pass result.
git status --short
git diff --stat
git diff -- package.json package-lock.json
git diff | grep -nE "sk_live_|sk-[A-Za-z0-9]{20,}|BEGIN PRIVATE KEY|password\s*="
git log --all -p -S"BEGIN PRIVATE KEY" | head -50
npm audit --omit=dev
git ls-files | grep -E "^\.env"Tuning permissions without losing control
If the approval prompts slow you down, narrow them instead of removing them. Add specific read-only commands to the allowlist, such as listing files or running your test suite, and put destructive verbs on the deny list. Because the documentation says a command matching both lists requires approval, a deny entry is a safety net over a broad allowlist entry, but do not rely on that alone. A single broad entry such as a bare shell name approves far more than you meant.
Keep production out of reach. Run the agent against a development database with disposable data, and keep production credentials out of the shell it uses. Prefer scoped, revocable tokens. If a team administrator sets a maximum level, treat that as a floor you are glad to have.
For MCP servers, the documentation notes that tool calls can run code written by arbitrary server authors and disclaims liability for failures. Read that literally. Install servers from sources you can identify, check what commands they launch, give them the least access that works, and remove the ones you stop using. Team plans can restrict servers to an allowlist, so use it if you can.
Common mistakes with this workflow
- Switching to the most automatic level for a long task and forgetting to switch back.
- Adding a broad command to the allowlist and assuming the deny list covers every dangerous case.
- Running the agent with production credentials in the environment.
- Committing large AI diffs unread because the app appears to work.
- Installing MCP servers from unknown sources or leaving unused ones connected.
- Storing a key in a rules file or in a saved memory.
- Trusting the documentation you remember. Names and settings changed, so check the current site.
Test the result, not the assistant's summary
After a session, start the app locally and call each route the way an attacker would, without a session and with the wrong user's session. Compare fields returned in responses with what the screen shows. Read new dependencies and confirm they are needed. An agent's final message describes intent, and only requests and diffs show what actually happened.
The first call must be rejected as unauthenticated and the second must be refused or return nothing. Adjust the paths and token style to your own project.
export BASE="http://localhost:3000"
curl -i "$BASE/api/records/RECORD_ID_OWNED_BY_USER_A"
curl -i "$BASE/api/records/RECORD_ID_OWNED_BY_USER_A" \
-H "Authorization: Bearer USER_B_TOKEN"Keep it working
Recheck your auto-execution level, both lists and your MCP servers after each update and before starting long unattended tasks. Run the diff, secret and audit commands before every commit. Pass condition: nothing destructive can run without your approval, no secret is tracked or in history, and every merged AI change has been read and tested against the running app.
Frequently asked questions
Which auto-execution level should I use?
The documentation describes disabled, allowlist only, auto and turbo. For anything touching real data or credentials, prefer the stricter levels with a short allowlist. Use the fully automatic level only inside a disposable environment. Confirm the current names and behavior in your version.
Is Windsurf the same as Devin Desktop?
The Windsurf documentation address now redirects to a Devin Desktop site that mentions Windsurf as a previous name. Because branding and settings may have changed, follow the current documentation for your installed version rather than older guides.
Are MCP servers safe to install?
Not automatically. The documentation says MCP tool calls can invoke code written by arbitrary server implementers. Install only servers you can identify, review what they run, grant minimal credentials and use administrator allowlists where your plan offers them.
Does the agent's own review catch security problems?
It can help surface some, but it is not a substitute for reading diffs and testing your app. Confirm authorization, input handling and secret hygiene with your own commands and requests after each session.