Claude Code is not a chatbot in a browser tab. It is an autonomous coding agent that reads your files, runs shell commands, edits source, calls tools, and reaches the network — on your machine, with your credentials, inside your repository. That is exactly what makes it useful, and exactly what makes it a security surface. The same principle that governs every agentic system applies here: autonomy is blast radius. Hardening Claude Code is not a matter of trusting the model more or less. It is a matter of deliberately configuring what the agent is allowed to do, so that a mistake — or a manipulated instruction — cannot reach further than you intended.

The good news is that Claude Code ships with a strong default posture and a rich set of controls. The work is knowing them and setting them on purpose. This guide distils Anthropic’s official Claude Code security documentation (code.claude.com/docs/en/security) into an opinionated hardening workflow — the permission model, the built-in defences, and the settings that meaningfully reduce blast radius.

Start from the default posture

Claude Code is permission-based and read-only by default. It can inspect your code freely, but anything that modifies your system — editing files, running non-trivial shell commands, executing tools — requires explicit approval. A small built-in set of read-only commands (ls, cat, git status and similar) runs without a prompt; everything else asks. Two boundaries matter most out of the box:

  • Working-directory boundary: Claude Code can only write to the folder it was started in and its subfolders. It cannot modify files in parent directories without explicit permission. Reading outside that boundary with Read, Grep and Glob is possible only after an approval prompt.
  • Trust verification: the first run in a new codebase, and every new MCP server, requires you to confirm trust. Two sharp edges are worth knowing: trust verification is disabled when you run non-interactively with the -p flag, and starting Claude Code directly in your home directory only holds trust for the session (it re-prompts every launch). Start it from a project subdirectory instead, where trust is saved per directory.

Claude Code only has the permissions you grant it. You are responsible for reviewing proposed code and commands before you approve them.

Master the permission model

The permission system is the single most important control, so treat settings.json as a security artefact, not a convenience file. Permissions resolve to three outcomes — allow, ask, deny — and the matching is deliberately conservative:

  • Fail-closed matching: any command that does not match an allow rule defaults to requiring manual approval. Silence means “ask”, never “allow”.
  • Command-injection detection: a suspicious shell command is escalated to manual approval even if it would otherwise match an allowlist. Allowlisting is not a blank cheque.
  • deny beats allow: use permissions.deny to hard-block things you never want the agent to touch — for example blocking network fetchers with rules like Bash(curl *) and Bash(wget *), or denying reads of secrets directories. A deny rule cannot be overridden by an allow rule or by in-session approval.

Understand the permission modes, because they trade prompts for autonomy — and blast radius. The default mode asks before acting. Accept Edits mode auto-approves file edits and a fixed set of filesystem Bash commands (mkdir, touch, rm, mv, cp, sed) for paths inside the working directory, while still prompting for other commands and out-of-scope paths. The lesson: reach for Accept Edits when you are actively supervising a scoped task, not as a permanent setting on a repository that matters. Audit what you have granted at any time with the /permissions command.

The prompt-injection defences — and their limits

Because Claude Code reads untrusted content (files, web pages, tool output), indirect prompt injection is a live risk: a malicious instruction planted in something the agent reads can try to redirect its behaviour. Claude Code layers several defences against this:

  • The permission system itself — sensitive operations require approval, so an injected instruction still has to get past you before it acts.
  • Context-aware analysis that inspects the full request for harmful instructions, and input sanitisation to prevent command injection.
  • Isolated context windows for web fetches, so content pulled from the internet cannot inject instructions into your main session.
  • Network-command approval: fetchers like curl and wget are not auto-approved — they prompt like any other non-read-only command, so exfiltration through a network call is not silent.
  • Fail-closed matching and command-injection detection, as above, so a hijacked instruction cannot quietly ride an existing allowlist.

These are real mitigations, but the documentation is refreshingly honest: no system is completely immune. The permission prompt is only as strong as the human reading it, which is why the operator’s discipline is part of the control set. Practical habits that matter:

  • Review every suggested command before you approve it — read what it actually does, not what the summary says it does.
  • Do not pipe untrusted content directly into Claude, and verify proposed changes to critical files by hand.
  • Run scripts and tool calls that touch external web services inside a virtual machine or container, so a successful injection is contained.
  • Report anything suspicious with /feedback.

Isolate: sandboxing, boundaries and containers

Defence in depth means assuming an approval will occasionally be wrong and constraining what a wrong approval can reach. Claude Code gives you three concentric layers of isolation:

  • The sandboxed Bash tool: enable it with /sandbox to run shell commands under filesystem and network isolation. This both reduces permission prompts (the agent can work autonomously inside the sandbox) and contains what those commands can do. When sandboxing is on, denyRead rules let you restrict the broader read access that read-only Bash commands otherwise have.
  • The working-directory boundary, covered above — extend it deliberately with additional directories only when you must, rather than starting the agent somewhere broad.
  • Dev containers and VMs: for sensitive repositories, run Claude Code inside a development container or a virtual machine so that even a full compromise of the agent’s permissions is bounded by the container, not your host.

Credentials, network and the Windows WebDAV trap

Claude Code stores API keys and tokens in the macOS Keychain when available, and protects them with file permissions on Windows and Linux. Beyond that, two things deserve explicit attention. First, keep network fetchers on a short leash — leave curl and wget prompting, or deny them outright in repositories that should never reach the internet. Second, a specific Windows warning: do not enable WebDAV or allow Claude Code to access \\* paths that may contain WebDAV subdirectories. WebDAV is deprecated by Microsoft for security reasons, and enabling it can let Claude Code trigger network requests to remote hosts that bypass the permission system entirely.

MCP servers are third-party code with your agent’s authority

Every MCP server you connect is code that runs with your agent’s authority and can expand its reach. Anthropic reviews connectors against listing criteria before adding them to its directory, but explicitly does not security-audit or manage MCP servers — that responsibility is yours. Two rules hold up well: prefer MCP servers you wrote yourself or that come from providers you already trust; and because the list of allowed MCP servers lives in your Claude Code settings checked into source control, treat that list the way you treat any dependency manifest — reviewed, minimal, and version-controlled.

Team and enterprise hardening

Individual discipline does not scale; policy does. For teams, move the controls from personal habit into enforced configuration:

  • Use managed settings to enforce organisational standards that individual developers cannot silently weaken.
  • Share approved permission configurations through version control, so the security posture of a repository is reviewed like any other change.
  • Audit or block settings changes mid-session with ConfigChange hooks — this closes the gap where an injected instruction or a hasty developer loosens permissions during a run.
  • Monitor usage through OpenTelemetry metrics, and audit permissions regularly with /permissions.
  • Train the team: the permission prompt is a human control, and humans need to know what a dangerous approval looks like.

Know your execution model: local, cloud, remote

Where Claude Code runs changes its threat model. Cloud execution (Claude Code on the web) runs each session in an isolated, Anthropic-managed VM with network access limited by default, credentials handled through a secure proxy that translates a scoped sandbox credential to your real token, git pushes restricted to the current branch, and full audit logging. Remote Control is different: the web interface drives a Claude Code process on your own machine, so all code execution and file access stays local, session traffic runs over TLS, and the connection uses multiple short-lived, narrowly scoped credentials to limit the blast radius of any single compromised one. Match your isolation choice to the sensitivity of the work.

A hardening checklist

  • Start Claude Code from the project subdirectory, never your home directory, so trust and the working-directory boundary work for you.
  • Treat settings.json as security config: explicit allow rules, deny rules for network fetchers and secrets, and rely on fail-closed defaults for everything else.
  • Keep the default permission mode for anything that matters; use Accept Edits only while actively supervising a scoped task.
  • Turn on the sandbox (/sandbox) for autonomous work, and add denyRead rules for sensitive paths.
  • Run sensitive repositories inside a dev container or VM; route anything touching external web services through isolation.
  • Vet every MCP server; keep the allowed-server list minimal and in source control.
  • For teams: managed settings, version-controlled permissions, ConfigChange hooks, OpenTelemetry monitoring, and regular /permissions audits.
  • Run /security-review over your branch, and use the security-guidance plugin to have Claude review and fix vulnerabilities in its own changes.

If you find a vulnerability

If you discover a security vulnerability in Claude Code itself, do not disclose it publicly. Report it through Anthropic’s HackerOne program with detailed reproduction steps, and allow time for a fix before any public disclosure. Responsible disclosure is part of keeping the tooling everyone relies on safe.

The bottom line

Claude Code’s defaults are genuinely good — read-only, permission-gated, boundaried, fail-closed. But defaults are a starting point, not a security posture. The teams that use it safely are the ones that treat the permission model as code, isolate the agent to match the sensitivity of the work, vet what they connect, and remember that the approval prompt is a human control that still requires a human paying attention. The controls exist. Hardening is the deliberate act of turning them on.