AI IDEs and terminal coding agents ship with settings that decide whether the agent asks before it runs a shell command, reads a file outside the project or calls the network, and most organisations leave those settings to individual developers. Cursor, Claude Code, Windsurf and GitHub Copilot agent mode in VS Code each now offer permission modes, command allow and deny lists, OS-level sandboxes, hooks and centrally managed policy. They differ in names, defaults and in what each control actually enforces. This guide is the product-configuration view: what each tool documents, which settings matter, how to enforce them centrally and where the controls stop. It is for platform, endpoint and application security teams standardising developer tooling. For the wider threat model and CI/CD agents, see the AI Coding Agents Security Guide. Product details below were checked against vendor documentation on 24 October 2026 and change often.
Key takeaways
- Every tool says its allow-lists are not a security boundary. Claude Code, Cursor and VS Code documentation each state that command matching or classifier review is best effort; use OS sandboxing and credential scoping for enforcement.
- Sandboxes exist but defaults vary. Claude Code's sandbox is off by default; Cursor and VS Code sandbox terminal commands under certain modes; read access outside the project is often allowed by default.
- Central policy is available in all four. Managed settings, team dashboards and enterprise policies can cap modes, block bypass modes and enforce sandboxing, and they override developer and repository settings.
- Repository files configure the agent. Committed settings, rules, hooks and MCP configuration travel with a clone, so workspace trust and code owner review matter as much as personal settings.
- The agent holds the developer's credentials. Whatever the settings, tokens reachable from the workspace are reachable by the agent, as the PocketOS deletion showed.
Scope: what this guide covers
The AI Coding Agents Security Guide explains why coding agents are risky and the general controls: sandboxes, scoped credentials, human approval for irreversible actions and workload identities in CI/CD. This guide does not repeat that. It answers the next question a platform team asks: which settings, in which file, in which product, implement those controls, and how do we stop a developer or a cloned repository from loosening them? It covers local IDE and terminal agents. Cloud agents are mentioned only where a product's local settings do not apply to them; for example, Cursor documents that its run modes apply to local agents only and that Cloud Agents never prompt for approval.
The four products at a glance
| Area | Claude Code | Cursor | Windsurf (Devin Desktop) | Copilot agent mode (VS Code) |
|---|---|---|---|---|
| Approval modes | default (Manual), acceptEdits, plan, auto, dontAsk, bypassPermissions | Auto-review (default), Allowlist, Run Everything | Cascade auto-execution: Disabled, Allowlist Only, Auto, Turbo | Manual, Assisted (experimental), Allow all, Autopilot |
| Command rules | permissions.allow, ask, deny; deny then ask then allow | Allowlist; classifier guidance via allow_instructions and block_instructions in permissions.json | Allow list and Deny list; deny wins | chat.tools.terminal.autoApprove with true/false and regex; false wins |
| OS sandbox | Seatbelt (macOS), bubblewrap (Linux, WSL2); off by default | Seatbelt (macOS), Landlock or Bubblewrap (Linux) | Not described on the terminal page read | chat.agent.sandbox.enabled; restricts terminal file and network access |
| Hooks | PreToolUse and others; cannot override deny or ask rules | hooks.json: beforeShellExecution, beforeMCPExecution, beforeReadFile and others | Not covered here | preToolUse hooks return allow, deny or ask |
| Central enforcement | Managed settings (file, MDM, server-managed); allowManagedPermissionRulesOnly | Team dashboard overrides local; enterprise hooks.json via MDM | Admin Portal caps maximum level; team allow and deny lists | Enterprise policies such as ChatAgentMode, ChatMCP, ChatToolsAutoApprove |
Windsurf's documentation now redirects to docs.devin.ai, where the editor is documented as Devin Desktop with Cascade as its agent. Check which name your licence and admin portal use.
Comparing permission modes by risk
Every product offers a spectrum from "ask for everything" to "run everything". Map them to a common risk tier so policy can be written once.
| Risk tier | Claude Code | Cursor | Windsurf | VS Code Copilot | Suggested policy |
|---|---|---|---|---|---|
| Read-only planning | plan | Allowlist with empty list | Disabled | Manual | Default for unfamiliar or untrusted repositories |
| Approve each action | default | Allowlist | Allowlist Only | Manual | Standard developer default |
| Model or classifier decides | auto | Auto-review | Auto | Assisted | Allowed with sandbox on and secrets out of reach |
| No prompts | bypassPermissions | Run Everything | Turbo | Allow all, Autopilot, /yolo | Only in disposable containers or VMs; block on managed endpoints |
Claude Code's dontAsk mode is a useful extra for scripted runs: it denies anything that would otherwise prompt, so only pre-approved tools run.
Claude Code configuration
- Settings scopes: managed settings, then command line (
--settings), then.claude/settings.local.json, then the shared.claude/settings.json, then~/.claude/settings.json. List keys such aspermissions.allowmerge across files rather than replacing each other. Run/statusto see the "Setting sources" in effect. - Rule order: deny, then ask, then allow; the first match in that order wins, and an allow rule cannot carve an exception out of a deny. A deny at any level, including user level, blocks a project-level allow.
- Compound commands: rules are matched per subcommand across
&&,||,;,|and newlines, so allowingBash(npm run test *)does not approve a chained second command. The documentation also states that Bash rules match command text, not the program:Bash(curl *)in deny does not stop/usr/bin/curlorsh -c. It points to sandboxing for enforcement. - Lock out bypass: set
permissions.disableBypassPermissionsModeand, if required,permissions.disableAutoModeto"disable"in managed settings.allowManagedPermissionRulesOnlymakes managed settings the only source of permission rules.defaultModevaluesautoandbypassPermissionsare ignored from project and local files. - Sandbox: enable with
"sandbox": {"enabled": true}. For enforcement setfailIfUnavailable: trueandallowUnsandboxedCommands: falsein managed settings. By default writes are confined to the working directory but reads cover most of the machine, including~/.sshand~/.aws/credentials; addsandbox.filesystem.denyReadentries orpermissions.blockReadsOutsideWorkingDirectories. Network traffic goes through a proxy with an emptysandbox.network.allowedDomainslist to start;allowManagedDomainsOnlyrestricts it to the managed list. - Sandbox limits: the sandbox covers shell commands, not the built-in Read and Edit tools, MCP servers or hooks. The documentation warns that broad allowed domains such as
github.comcan enable exfiltration, that allowing/var/run/docker.sockeffectively grants host access, and thatexcludedCommandsrun with full access. - Repository trust:
permissions.allowrules andadditionalDirectoriesfrom a committed.claude/settings.jsonapply only after the developer accepts the workspace trust dialog, which lists them; deny and ask rules apply immediately. Non-interactiveclaude -pand SDK runs never show the dialog, so review repository settings before running headless jobs on unfamiliar code. - Hooks: a
PreToolUsehook can block a call (exit code 2) even when an allow rule matches, but cannot override a deny or ask rule. Use hooks for custom inspection, such as blocking commands that reference credential paths.
Cursor configuration
- Run modes: Auto-review is the recommended default: allowlisted calls run, other shell commands run in the sandbox where possible, and anything else goes to a backend classifier. Cursor's documentation states that Auto-review is not a security boundary and that the classifier can make mistakes in both directions. Allowlist runs only listed actions without approval; Run Everything runs every tool call with no sandbox. "Ask Every Time" was deprecated in version 3.5 in favour of Allowlist with an empty list.
- Configuration files:
permissions.jsonandsandbox.jsonlive in~/.cursor/and<project>/.cursor/. A team configuration in the dashboard overrides local files, and the documentation says team policies and hard-coded security rules cannot be weakened locally. - Sandbox: read and write inside the workspace, with protected paths including
.git/config,.git/hooks,.vscodeand.cursorignore. Network is blocked by default and then opened by mode: "sandbox.json Only", "sandbox.json + Defaults" (the default, adding Cursor's package manager and tooling domains) or "Allow All". - Read boundary: from version 3.23 the default "System" read access lets the agent read files outside the workspace without approval; "Workspace" requires approval except for paths on the Read Allowlist (
readBoundary,additionalReadPathsinsandbox.json). Set Workspace where home directories hold credentials. - Extra protections: File-Deletion Protection, External-File Protection and Browser Protection force approval even in automatic modes. Enable them as a baseline.
- Hooks:
hooks.jsonis read from enterprise system paths (for example/etc/cursor/hooks.jsonon Linux), a team dashboard, the project.cursor/hooks.jsonand the user~/.cursor/hooks.json.beforeShellExecutionandbeforeMCPExecutioncan return allow, deny or ask;beforeReadFilecan deny reads of sensitive files. The enterprise path is the place for organisation-wide inspection hooks. - Rules files: project rules such as
.cursor/rulesand legacy.cursorrulesshape agent behaviour and arrive with a clone. Treat them as code.
Windsurf (Devin Desktop) configuration
- Auto-execution levels: Disabled (every command needs approval), Allowlist Only, Auto (the agent judges safety; premium models only) and Turbo (everything runs except deny-listed commands).
- Lists: entries ending in a space and
*match every command with the same leading tokens; others match exactly. The deny list takes precedence, so a command on both lists needs approval. A broad entry such asgit *auto-runs every Git subcommand, including ones that push or rewrite history. - Admin controls: on Teams and Enterprise plans admins can cap the maximum auto-execution level, which is how to block Turbo organisation-wide, and set team allow and deny lists under Team Settings, Terminal Commands, Manage Lists. Team lists merge with personal lists and the team deny list takes precedence.
- Environment inheritance: the agent's terminal inherits aliases and environment variables from shell configuration files, so credentials exported in
.zshrcor.bashrcare visible to it.
GitHub Copilot agent mode in VS Code
- Permission levels: Manual (default), Assisted (an LLM judge, experimental), Allow all and Autopilot.
chat.permissions.defaultsets the starting level;chat.tools.global.autoApproveand the/yolocommand approve everything. - Terminal rules:
chat.tools.terminal.autoApprovetakes command prefixes or regular expressions wrapped in/. A compound command auto-runs only if every subcommand matches atruerule and none matchesfalse. VS Code describes terminal auto-approval as "a best-effort convenience, not a security boundary", noting parsing gaps and bypass through aliases or quote concatenation. - URLs and files:
chat.tools.urls.autoApproveseparates approving the request from approving the response entering context.chat.tools.edits.autoApprovewith patterns such as"**/.env": falseforces approval for edits to sensitive files. - Sandbox:
chat.agent.sandbox.enabledconfines terminal commands and child processes and applies under every permission level, including Allow all and Autopilot. Outbound network is governed bychat.agent.sandbox.network.allowNetwork, which defaults totrue, so set it deliberately. The documentation says the sandbox is not a VM or user-account boundary and recommends a dev container for stronger isolation. Platform support is listed as preview on macOS, Linux and WSL2, with Windows marked experimental on the approvals page. - Workspace trust and MCP: restricted mode disables agents in untrusted workspaces, and MCP servers in
.vscode/mcp.jsoninherit workspace trust. - Enterprise policies:
ChatAgentModedisables agent mode;ChatMCPset toregistryOnlyoroffwithMcpGalleryServiceUrlpointing at a private registry;ChatToolsAutoApproveblocks global auto-approval;ChatToolsTerminalEnableAutoApprovedisables terminal auto-approval rules. VS Code notes that some policies are not fully enforced in Copilot harness sessions, for exampleChatMCPdoes not cover MCP servers the runtime discovers itself. See the GitHub Copilot Security Guide.
Repository-supplied configuration and instruction files
Each tool reads configuration from the repository: .claude/settings.json, CLAUDE.md, .cursor/ rules, permissions and hooks, .vscode/settings.json and .vscode/mcp.json. Opening a hostile repository can therefore change what the agent is told and, if trust is granted, what it may do. In the TrapDoor supply chain campaign, malicious npm packages wrote .cursorrules and CLAUDE.md files with hidden zero-width Unicode instructions aimed at getting Cursor and Claude Code to locate and send out secrets.
- Trust deliberately: open unfamiliar repositories in restricted mode or plan mode, and read the trust dialog's list of rules before accepting.
- Protect config paths: add
.claude/,.cursor/,.vscode/, instruction files and MCP configuration to CODEOWNERS and scan them for hidden Unicode. - Prefer managed over repository: where a control matters, set it in managed or team settings, which override repository files in all four products.
See the MCP Security Guide for MCP server approval and the Prompt Injection Guide for why tool output is untrusted.
Where identity fits
An IDE agent has no identity of its own on the developer's machine: it acts with the developer's Git credentials, cloud CLI sessions, SSH keys, .env files and any API key pasted into an extension. Configuration narrows what the agent will do; it does not change what those credentials can do.
- Remove ambient secrets: keep long-lived keys out of the workspace and shell profile. Claude Code's sandbox supports
sandbox.credentialsentries that deny or mask environment variables and files, and itsCLAUDE_CODE_SUBPROCESS_ENV_SCRUBvariable strips credentials from subprocesses. - Scope what remains: use per-environment, per-purpose tokens with short lifetimes. See the Secrets Management Guide and the Agentic AI Identity Guide.
- Control extensions: AI plugins that ask for provider API keys become custodians of those keys. Use allow-listed extensions and separate, capped keys per tool.
Lessons from incidents
- Prefix allow-lists fail open: in the Gemini CLI prompt injection flaw, a poisoned README led the agent to run a command that began with an allow-listed
grepand chained an exfiltration command after it; Google fixed it in version 0.1.14. Prefer tools that split compound commands, and keep allow-lists to narrow, read-only commands. - Found credentials get used: in the PocketOS database deletion, an agent running in Cursor found an account-scoped Railway token in an unrelated file and deleted a production volume. Read boundaries and secret removal would have changed the outcome more than command rules.
- Tool output is input: in Sentry MCP agentjacking, researchers planted fake error reports that Claude Code, Cursor and Codex read through an MCP server and acted on with the developer's privileges. Require approval for commands derived from MCP output and limit network egress.
- Extensions steal keys: in the JetBrains Marketplace AI plugin campaign, 15 working AI assistant plugins sent saved provider API keys in plaintext to an attacker server.
- The agent itself can be poisoned: the Amazon Q Developer extension compromise shipped a destructive prompt in version 1.84.0. Pin and stage agent extension updates as you would any privileged software.
- Instructions are not permissions: in the Replit agent database deletion, a code freeze stated in natural language was ignored. Enforce freezes with modes, deny rules and credential changes.
Common failure patterns
- Leaving modes to developers: no managed or team policy, so Turbo, Run Everything or
bypassPermissionsbecomes the norm on laptops holding production credentials. - Treating the allow-list as the control: broad entries such as
git *ornpm *, with no sandbox, relying on parsing every vendor calls best effort. - Sandbox on, reads open: enabling a sandbox while leaving default read access to
~/.ssh,~/.awsand other projects. - Broad egress: allowing whole code-hosting or cloud domains in the sandbox network list, which provides an exfiltration route.
- Trusting every folder: accepting workspace trust by reflex, letting committed allow rules, hooks and MCP servers take effect.
Rolling out a baseline
- Inventory: identify installed AI IDEs, extensions and CLI agents through endpoint management and licence data. See the Shadow AI Discovery Guide.
- Define the baseline per tier: using the risk-tier table, pick the default mode, the blocked modes, sandbox and read-boundary settings, and a short allow-list of read-only commands.
- Deliver centrally: Claude Code managed settings (file, MDM or server-managed), Cursor team dashboard and enterprise
hooks.json, Windsurf Admin Portal caps and team lists, VS Code enterprise policies. - Pilot: apply to one team for two weeks with the sandbox enabled but not yet fail-closed, collect broken workflows (Docker, database clients and tools that ignore proxy variables are documented problem areas) and add narrow exceptions.
- Enforce: switch to strict settings: Claude Code
failIfUnavailableandallowUnsandboxedCommands: false, Cursor mode restrictions, Windsurf cap below Turbo, VS Code sandbox required. - Provide an escape hatch: a disposable dev container or VM where bypass modes are allowed, with no production credentials.
- Roll back safely: keep previous managed settings versions; if a release breaks builds, revert the specific key rather than removing the policy, and record the exception with an expiry date.
Detection and measurement
Collect: managed-settings delivery status per device, mode in use per session where the product reports it, hook logs from beforeShellExecution or PreToolUse, sandbox network denials, edits to agent configuration paths, and endpoint telemetry for agent child processes reading credential files. Metrics:
- Policy coverage: percentage of developer endpoints with managed AI IDE settings applied.
- Bypass exposure: number of sessions or devices running no-prompt modes outside approved containers.
- Sandbox enforcement: share of agent shell commands executed inside the sandbox.
- Credential reach: count of long-lived secrets readable from developer workspaces, from periodic scans.
- Egress denials: sandbox network denials per week, reviewed for exfiltration attempts.
Framework mapping
| Framework | Reference | Relevance |
|---|---|---|
| NIST SP 800-53 Rev. 5 | AC-6, CM-7, CM-11, SI-7 | Least privilege, least functionality, user-installed software, software integrity |
| NIST CSF 2.0 | PR.AA-05, DE.CM-09 | Least-privilege permissions; monitoring runtime environments |
| CIS Controls v8.1 | Control 2, Control 4 | Software inventory and allow-listing; secure configuration of endpoints and software |
| ISO/IEC 27001:2022 Annex A | A.8.19, A.8.2 | Installation of software on operational systems; privileged access rights |
| MITRE ATT&CK | T1195.001, T1552.001, T1552.004, T1546.004, T1485 | Poisoned dev tools, credentials in files, private keys, shell configuration persistence, data destruction |
| MITRE ATLAS | AML.T0051.001, AML.T0053 | Indirect prompt injection; AI agent tool invocation |
| OWASP Top 10 for LLM Applications 2025 | LLM01, LLM06 | Prompt injection; excessive agency |
Practitioner checklist
- Deliver AI IDE settings centrally for every product in use and verify coverage per device.
- Block no-prompt modes (
bypassPermissions, Run Everything, Turbo, Allow all) on managed endpoints; allow them only in disposable containers. - Require the OS sandbox where available and make it fail closed.
- Restrict reads outside the workspace and deny reads of credential paths.
- Keep sandbox network allow-lists narrow; avoid whole code-hosting domains.
- Limit command allow-lists to specific read-only commands and never rely on them as the boundary.
- Put agent configuration, instruction and MCP files under code owner review and scan for hidden Unicode.
- Deploy organisation-wide inspection hooks through enterprise paths.
- Remove long-lived secrets from workspaces and shell profiles; issue short-lived, scoped tokens.
- Allow-list AI extensions and pin agent tool versions with staged updates.
Standards and references
- Anthropic: Claude Code, Configure permissions
- Anthropic: Claude Code, Sandboxing
- Anthropic: Claude Code, Settings files and precedence
- Cursor: Run Modes
- Cursor: Hooks
- Devin Docs: Desktop Terminal (formerly Windsurf documentation)
- Microsoft: VS Code, Security for agents
- Microsoft: VS Code, Manage approvals and permissions
Related NHI Mgmt Group resources: AI Coding Agents Security Guide · Secure Coding Guide · AI-Generated Code Review Guide · MCP Security Guide · Vibe Coding Security Guide