Practice

Trust & Autonomy

How much freedom do you give Claude? The spectrum from cautious to fully autonomous.

The spectrum

Every time Claude wants to do something - edit a file, run a command, make an API call - it asks for permission. This is good for safety. It’s terrible for flow.

More autonomy is clearly better. The question is how much, and what safety nets to keep. There’s a spectrum:

Cautious ←————————————————————————————→ Autonomous
  │                                          │
  Ask for                               Skip all
  everything                            permissions

Most people stay too far left. They click “approve” hundreds of times per session, which defeats the point.

Permissions: your allow/deny list

Claude Code’s permission system lets you pre-approve specific actions. In ~/.claude/settings.json:

{
  "permissions": {
    "allow": [
      "Read",
      "Glob",
      "Grep",
      "WebSearch",
      "Bash(git status*)",
      "Bash(git log*)",
      "Bash(bun *)",
      "Bash(mkdir *)"
    ],
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)",
      "Bash(git reset --hard*)"
    ]
  }
}

The allow list is what Claude can do without asking. The deny list is what Claude can never do, even if you approve it in conversation.

My approach

I allow most read operations and common development commands. I deny destructive operations. The middle ground - editing files, running builds, git pushes - depends on context.

Setting "defaultMode": "acceptEdits" auto-accepts file edits, which eliminates the most common permission prompt. Claude can read, search, and edit files freely, but still asks before running anything unusual.

This gets me through most sessions with zero permission prompts for routine work, while still catching anything unexpected.

Sandboxing

If you want Claude to work fully autonomously - no permission prompts at all - you need isolation. Three approaches, from simplest to most secure:

Native sandbox

Built into Claude Code. Restricts file and network access at the OS level.

/sandbox

This opens a menu where you can enable sandbox mode. Claude can only access your current working directory. Bash commands run without permission prompts. Network access is restricted.

On macOS this uses Seatbelt, on Linux it uses bubblewrap. It’s OS-level isolation, not just a flag.

Docker sandbox

Run Claude in a container. Stronger isolation, still local.

docker sandbox run -w ~/my-project claude

Comes with Node.js, Python, Go, Git pre-installed. Full autonomy mode is enabled by default inside the container. Docker Sandboxes (launched January 2026) use microVM isolation - stronger than traditional containers.

Remote VM

The most isolated option. Claude runs on a cloud server, completely separate from your machine.

I use a Hetzner VM with git worktrees: Claude works in ~/work/ on feature branches, never touching main. When it’s done, I review the diff and merge what’s good.

This is the “test kitchen” approach - Claude experiments freely, nothing touches the real environment until I explicitly merge it.

Which to choose?

ApproachIsolationSetupBest for
Permissions onlyLowNoneDaily work, trusted projects
Native sandboxMediumNoneAutonomous tasks, single project
DockerHighMinimalLocal development, testing
Remote VMHighestMore workLong-running autonomous work

Worktrees: built-in isolation

Claude Code has native worktree support - a way to create isolated copies of your repo for Claude to work in:

claude --worktree feature-name
# or
claude -w

This creates a worktree at <repo>/.claude/worktrees/<name>/ on a separate branch. Claude works freely. If the changes are good, you merge. If not, the worktree gets cleaned up automatically.

For developers, this is the easiest way to let Claude experiment without risking your working copy. Each worktree is independent - you can have multiple running on different features.

Worktrees are cheap and disposable. Create them freely, merge what works, delete what doesn’t. Your main branch stays clean.

Hooks

Hooks are commands that run automatically when Claude does something. They’re configured in ~/.claude/settings.json.

I’ll be honest: I use exactly one hook.

{
  "hooks": {
    "PreCompact": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "~/bin/claude-memory sync -q",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Before Claude compacts (summarizes) the conversation to free up context, this hook syncs my conversation history to the search index. That way, even compressed conversations are searchable later.

What hooks can do

Hooks run on various events - before/after tool calls, when sessions start or end, when files are edited. Some ideas:

  • Auto-format on edit - Run prettier after Claude edits a file
  • Lint check - Run your linter after changes
  • Notification - Play a sound when a long task finishes
  • Backup - Copy a file before Claude modifies it

The event system is extensive (18 events and counting), but the principle is simple: “When X happens, also do Y.” Start with one hook that solves a real problem. Add more only when you need them.

For hooks you don’t always want running, a simple toggle:

# In your hook script
if [ ! -f ~/.claude/hooks-enabled ]; then
  exit 0
fi
# ... rest of hook

Control with: touch ~/.claude/hooks-enabled or rm ~/.claude/hooks-enabled.

What autonomy doesn’t protect against

More autonomy means more trust. Worth knowing what that trust actually buys you.

What sandboxing and permissions protect against:

  • Accidental deletions (git history preserves everything)
  • Silent changes (must review diff before merge)
  • Blast radius (sandbox can’t touch outside files)

What they do NOT protect against:

  • Prompt injection (malicious content in files could trick Claude)
  • Credential exposure (API keys, SSH keys are accessible to Claude in your environment)
  • Malicious code (Claude could write backdoors - review carefully)

Mitigations:

  • Review diffs before merging, especially for code
  • Use repo-specific deploy keys, not your personal SSH key
  • Don’t store secrets in repos Claude can access

The real protection

Git is the real safety net. Every change is tracked. Nothing is permanent until you commit. Something goes wrong? git diff shows what happened, git checkout undoes it.

My setup

For reference, here’s where I’ve landed after months of iteration:

  • Permissions: Read/search/edit allowed. Destructive git operations denied. Common CLI tools allowed.
  • Default mode: acceptEdits - file changes don’t prompt.
  • Hooks: One - conversation sync before compaction.
  • Sandbox: Not used for daily work. Used for autonomous VM sessions.
  • Worktrees: Used for experimental features and Claude-driven refactors.

This lets me work without friction most of the time. Your setup will look different depending on what you do and how much you trust Claude with it.


Official Documentation

  • Permissions - Understanding and configuring Claude Code permissions
  • Sandboxing - Running Claude Code in isolated environments
  • Hooks - Automating actions based on Claude Code events