The short answer
Cursor’s auto-run is controlled in Settings > Agents > Approvals & Execution, where you pick one of three run modes: Auto-review, Allowlist or Run Everything.1 Two optional files sit behind them. permissions.json holds plain-English instructions that steer Auto-review’s classifier. sandbox.json sets what a sandboxed command can read, write and reach on the network.1 The allowlist itself is coarse: in Cursor’s CLI, Shell(git) matches any command whose first word is git, including git clean and git push --force.3 So keep the allowlist short and let sandbox.json do the limiting.
Our earlier post on Cursor deleting files covers which protection stops rm. This one covers the configuration files, how they merge, and what a team admin can lock.
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
Three modes in one paragraph
Out of the box, terminal commands need your approval, MCP connections need approval, and each MCP tool call needs approval unless the tool is on an MCP allowlist.4 The run modes change that:
| Mode | Runs without asking | Sandbox | Classifier |
|---|---|---|---|
| Auto-review | Allowlisted calls; other shell commands in the sandbox when they fit | Yes, for shell | Yes |
| Allowlist | Only what’s on your list | Optional | No |
| Run Everything | Every tool call | No | No |
Source: Cursor’s Run Modes page.1 Auto-review became the recommended default in Cursor 3.6 on 29 May 2026, a week after 3.5 retired the old Ask Every Time mode; an Allowlist with an empty list gives the same behaviour.1
Auto-review covers shell, MCP and Fetch calls. A call that can’t use the sandbox goes to a classifier that runs on Cursor’s backend. To judge it, the classifier can make read-only ReadFile, Grep, Glob and ListDir calls on your machine, for example to read the script a command would run.1 Cursor is direct about the limit: “Auto-review is not a security boundary.” The classifier can allow a call you would have blocked.1
What an allowlist entry really allows
The allowlist is where most trouble starts, because entries are shorter than the commands they approve.
Cursor documents the matching rules most precisely for its CLI. A Shell(commandBase) rule matches the first token of the command line, globs work, and an optional command:args form matches arguments too.3 The docs’ own examples show the consequence:
| Entry | What it approves |
|---|---|
Shell(ls) |
Any ls command |
Shell(git) |
Any git subcommand, including git clean -fdx and git push --force |
Shell(npm) |
Any npm command, including npm publish and install scripts |
Shell(curl:*) |
curl with any arguments |
Source: Cursor’s CLI permissions reference.3 Deny rules take precedence over allow rules, so a Shell(rm) deny entry survives a broad allow list.3
Allowlists also read text, and text can hide things. In 2025 Cursor fixed an advisory where, in auto-run mode with an allowlist, a backtick or $(cmd) let a command slip past the list; the allowlist moved to a more robust parser in 1.3.5 Our review of Cursor’s 33 advisories counts three allowlist bypasses in all. The lesson isn’t that Cursor’s parser is weak. It’s that any control that inspects a command string is one layer, not the wall.
Three rules for the list:
- Allow read-only verbs, not tools.
Shell(ls),Shell(cat)andShell(rg)are fine.Shell(git)is not. - Use the
command:argsform when you need one subcommand, so the entry names it. - Put destructive bases in deny:
rm,git clean,git push,psql,mysql,dropdb,terraform,kubectl.
permissions.json steers the classifier
permissions.json is the file people confuse with an allowlist. It isn’t one. It holds two lists of plain-English sentences, allow_instructions and block_instructions, which Auto-review leans toward.1
Code Data in JSON, the format software uses to pass records and settings.
{
"autoRun": {
"allow_instructions": [],
"block_instructions": [
"Every command that connects to a production database should go through approval first.",
"Every command that modifies Kubernetes resources should go through approval first."
]
}
}
Cursor reads it from ~/.cursor/permissions.json and <project>/.cursor/permissions.json and merges the two.1 You can commit the project file so the whole team gets the same guidance.
Because the instructions go to a classifier, they are probabilistic. A block instruction raises the odds of a prompt; it doesn’t make one certain. Use it for judgment calls (“anything that touches billing”), and use deny rules or the sandbox for things that must never run unattended.
sandbox.json sets the walls
sandbox.json is the file that changes what a command can physically do. It lives at ~/.cursor/sandbox.json and <workspace>/.cursor/sandbox.json; the two merge, the workspace file wins, and team-admin policies and Cursor’s hardcoded rules sit on top so neither file can weaken them.2
The defaults are sensible:
| Setting | Default | Meaning |
|---|---|---|
type |
workspace_readwrite |
Read and write inside the workspace; workspace_readonly and insecure_none (no sandbox) also exist |
networkPolicy.default |
deny |
Only allowed domains are reachable |
| Private addresses | Blocked | RFC 1918 ranges, 127.x and 169.254.169.254 are blocked by default |
| Matching | Domain or IP | URL paths are ignored |
Source: the sandbox.json reference.2 Network access has its own mode in settings: sandbox.json Only, sandbox.json + Defaults (the default, which adds Cursor’s list of package-manager domains) and Allow All.1
Two consequences matter for database work. First, a sandboxed command can’t reach a Postgres on 127.0.0.1 or a private subnet unless you allow it. That is a feature: an agent can’t psql your local database from inside the sandbox by accident. Second, when a command needs more access, it leaves the sandbox. In Auto-review, the classifier then decides.1 So the sandbox protects you only as long as risky commands stay in it.
Some paths are always write-protected, whatever the file says: .cursor/*.json, .claude/*.json, .vscode/**, .git/hooks/**, .git/config and .cursorignore.2 That list exists because agent configuration files are code; an agent that can edit its own allowlist has no allowlist.
Cursor 3.23 added a read boundary as well. With Read Access set to Workspace (or "readBoundary": "workspace" in sandbox.json), reads outside the workspace ask first unless the path is on your Read Allowlist.1 It is off by default, so turn it on if your home directory holds keys and dumps.
Team settings beat local files
For teams, the dashboard is the source of truth:
- A team Auto-review configuration takes priority, and Cursor then ignores the user and project
permissions.jsonfiles.1 - Sandbox policies merge per-user, then per-repo, then team-admin, then hardcoded. Network deny lists always add up; a team-admin network allowlist replaces the union of everyone else’s.2
- Admins can limit which run modes members may pick.1
One gap to know: Cloud Agents don’t use Run Modes at all. They run on their own machine and never ask for approval.1 Decide separately what credentials a cloud agent gets.
A setup we would start from
- Mode: Auto-review, or Allowlist if you want deterministic behaviour.
- Allowlist: read-only commands only. No
git,npm,dockeror database clients as bare bases. - Deny:
rm,git clean,git push, database clients, cloud CLIs. - permissions.json: block instructions for production hosts, migrations and anything that sends email or money.
- sandbox.json: keep
networkPolicy.defaultatdeny; add only the registries you use. - Protections: File-Deletion Protection and External-File Protection on.1
- Read boundary: Workspace, with a short Read Allowlist.
- Hook: a
beforeShellExecutionhook for the commands you never want to run unseen. It fails open by default unless you setfailClosed.6
What auto-run settings don’t cover
Every control above looks at the call before it runs: the command string, the classifier’s guess, the sandbox’s walls. None of them can tell you what a command changed once it ran. A psql command allowed outside the sandbox can update every row in a table, and the agent’s summary is the only account you get. Cursor’s own docs call these controls best-effort guardrails rather than a hard boundary.4
That is where a database-side check helps. deedglass guard shell installs as Cursor’s before-a-command hook, from the same table it uses for Claude Code, Codex CLI, Gemini CLI and GitHub Copilot.7 Like any hook, it is a second check, not a sandbox: if it can’t run, the command goes ahead unchecked.7 If you want to see auto-run, approvals and read-backs on a real database without installing anything, open the playground. To grade what an agent can reach on your own machine, including Cursor’s MCP config, run npx deedglass scan (the grade, explained).
Questions people ask
Is Cursor’s allowlist the same in the editor and the CLI?
The CLI documents its rule syntax (Shell(...), Mcp(...), WebFetch(...)) in cli-config.json or .cursor/cli.json.3 The editor manages its list in settings and from the approval card. Treat entries in both as approving every command that starts with the same word unless you scope them.
Does the denylist still exist?
In the CLI, yes: permissions.deny takes precedence over allow.3 In the editor, the closest equivalents are block instructions for Auto-review, the protections, and a hook that returns deny.
Should I use Run Everything in a container?
Only if the container has no credentials you’d miss. Run Everything has no sandbox and no classifier.1 If the container can reach a production database, so can the agent.
Written with AI assistance and checked against our claims register.