Claude Code is an agent with access to local data and tools, and this sets its threat model. Any text it reads may contain instructions: source code, an issue, a web page, a log, an MCP server's response, image metadata. Prompt injection is an attempt to make the model treat such untrusted text as a controlling command. The key understanding of the whole chapter: untrusted content is data, not commands, and the real security boundary runs not in the system prompt, which injection can bypass, but in permissions and the sandbox.
The official defense is built of several layers, and each has its own role and its own limit. Workspace trust reduces the automatic acceptance of project config from an unfamiliar checkout, but does not guarantee the safety of the text itself. Permission rules limit the launch of known tools, but not the meaning of an allowed operation. The sandbox limits a process's file and network impact, but not the correctness of an edit. Credential deny and mask cover the listed secrets, but not what is not listed. Hooks and human review add their own checks - and their own limits.
It helps to gather the defense layers into a table once: what each reduces and what it does not guarantee. Below is such a map - from workspace trust to human review. Its main lesson is that no layer is self-sufficient: each closes its class of risk and leaves another open. Security is born of a composition of layers, not of one switch, and a person approving a diff "without looking" nullifies the last layer no worse than a disabled sandbox.
| Layer | What it reduces | What it does not guarantee |
|---|---|---|
| workspace trust | Auto-accepting project config from a foreign checkout | The safety of the text itself |
| permission rules | Launch of known tools/inputs | The meaning of an allowed operation |
| sandbox | A process's file/network impact | The correctness of an edit |
| credential deny/mask | Reading the listed secrets | Protection of the unlisted |
| hooks | Deterministic event checks | The hook's own correctness |
| human review |
| Judging the diff and consequences |
| Safety when approving without looking |
Before opening an unfamiliar repository there is a checkable order. Verify the origin and the source of the archive. Review .claude/, .mcp.json, hooks, plugins and shell scripts as executable policy - because that is what it is. Do not approve workspace trust automatically. Run an unknown project without production credentials. Start with Manual or Plan and a strict sandbox. This order turns "just opened someone else's repository" into a conscious admission of executable configuration written by someone else.
Secrets obey a simple rule: they must not be where the model will read them. Do not paste API keys into a prompt, CLAUDE.md, a skill, an agent definition, committed settings, a test snapshot or a log. Use the provider's secret store and injection from the environment. Remember ANTHROPIC_API_KEY separately: it has authentication precedence and can quietly switch from a subscription to API billing - /status should show the expected provider. Deny-read for .env and keys is a useful baseline but not the only protection.
Third-party code needs the same wariness as any untrusted input. An MCP server gets exactly the data and authority its protocol grants; a plugin can ship skills, agents, hooks, MCP and an LSP at once; a hook is an ordinary program with the rights of the Claude Code process. Hence the discipline: pin and review the source, study the manifest and launch commands, check the passed scopes and variables, start with a test account, remove a server or plugin of unclear provenance and do not confuse presence in a marketplace with a security endorsement.
The engineering conclusion gathers it all into one architecture. The strongest practical protection is a composition: a disposable worktree or container, a minimal token, a domain allowlist, a deny on secrets, pointed tool rules and mandatory review of the diff and tests. No single switch replaces this composition. It is exactly the combination of layers, not the strictest of them alone, that makes the agent's autonomous work as safe as is at all achievable.
It helps to frame this once as a minimal security gate - a checklist before an autonomous run. Below it is: a limited scope, clean or saved git, no production secrets in the process, reviewed and trusted project configuration, an enabled sandbox with a controlled escape hatch, deploy and push in ask/deny, tests and review defined in advance, a simple rollback. The typical failure is trusting one layer; the right move is to pass the whole gate, because security here adds up rather than being chosen.
# A minimal security gate before an autonomous run
[ ] the task scope is limited
[ ] git status is clean or changes are saved
[ ] no production secrets in the process
[ ] project config reviewed and trusted
[ ] sandbox enabled; the escape hatch is controlled
[ ] deploy/push/delete stay ask/deny
[ ] tests and review defined before launch
[ ] there is a simple rollback: branch, checkpoint or disposable worktree