Every production agent needs permissions. Without them, the agent has your shell; with them, you choose what the agent can do and what it has to ask about. This page maps the permission surface of the main coding agents and gives a working baseline.
Bash(pnpm test), deny Bash(rm *)").Layer 3 is the only hard boundary. Layers 1 and 2 are soft — an error in the rules or a prompt injection can bypass them.
Configure in .claude/settings.json (project) or ~/.claude/settings.json (user):
{
"permissions": {
"allow": ["Bash(pnpm *)", "Bash(git status)", "Bash(git diff *)", "Read(*)", "Edit(*)"],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)",
"Bash(npm install *)",
"Read(.env*)",
"Read(**/secrets/**)"
]
}
}Modes — set with claude --permission-mode <mode>:
| Mode | When to use |
|---|---|
default | Prompts for any action not on the allowlist |
auto | Classifier model approves routine work, blocks suspicious |
acceptEdits | Edits auto-approved, everything else prompts |
bypass | No prompts — never use unattended except inside a sandbox |
Use /sandbox inside a session to enable OS-level isolation. See Claude Code permissions.
Sandboxing is on by default. Three autonomy levels:
The sandbox restricts filesystem and network by default — you lift restrictions per task.
Cursor surfaces approval modes in the Agent UI:
Rules live in .cursor/rules/*.mdc (see Cursor Guide) — these shape behavior, not permissions. Cursor has no equivalent to Claude Code's deny list; scope at the OS / VM level instead.
Cascade respects file-system scoping: it won't edit files outside the workspace. Cascade tools can be enabled/disabled per conversation via settings. For enterprise, Windsurf Teams/Enterprise plans add regex-based access control and admin-curated MCP registries.
| Tech | What it is | When to use |
|---|---|---|
| Devcontainer | VS Code-managed Docker container with the repo mounted | Most teams. Easy, reproducible, cross-platform. |
| Docker | Bare container | When you don't need VS Code tight integration |
| Firecracker / VM | Full hypervisor isolation | Multi-tenant agent SaaS, hostile workloads |
| macOS App Sandbox / Linux seccomp | Process-level syscall filter | What Codex CLI uses by default |
| GitHub Actions runner | Throwaway VM per run | CI-driven agent tasks (PR review bots, etc.) |
For interactive development: devcontainer is the default answer.
For a TypeScript/Next.js project using Claude Code, start with this and tighten over time:
{
"permissions": {
"allow": [
"Bash(pnpm install)",
"Bash(pnpm test*)",
"Bash(pnpm lint*)",
"Bash(pnpm format*)",
"Bash(pnpm build)",
"Bash(pnpm dev)",
"Bash(git status)",
"Bash(git diff *)",
"Bash(git log *)",
"Bash(git add *)",
"Bash(git commit -m *)",
"Read(*)",
"Edit(*)",
"Write(*)"
],
"deny": [
"Bash(rm -rf *)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(curl *)",
"Bash(wget *)",
"Bash(ssh *)",
"Bash(npm install *)",
"Bash(npm run *)",
"Read(.env)",
"Read(.env.*)",
"Read(**/credentials*)",
"Read(**/*.pem)",
"Read(**/*.key)"
]
}
}Adjust per project. The principle: allow what you use, deny what's risky, let the prompt cover the rest.
[y/N] on every action until you stop reading. Worse than denying nothing because you develop banner blindness.~/.ssh.Search for a command to run...