DEV Community

Claude code
Claude code

Posted on

Using Git Worktrees to Contain the Blast Radius of Agentic Coding Tasks

{"@context":"https://schema.org","@type":"Article","headline":"Using Git Worktrees to Contain the Blast Radius of Agentic Coding Tasks","keywords":"claude code worktree isolation","description":"Comprehensive guide to claude code worktree isolation — covering definitions, best practices, tools, and FAQs.","author":{"@type":"Organization","name":"CLaude coe ","url":"https://gtm-rho.vercel.app/"},"publisher":{"@type":"Organization","name":"CLaude coe ","url":"https://gtm-rho.vercel.app/"},"datePublished":"2026-06-15T07:30:00.082Z","dateModified":"2026-06-15T07:30:00.082Z","mainEntityOfPage":{"@type":"WebPage"}}
{"@context":"https://schema.org","@type":"FAQPage","mainEntity":[{"@type":"Question","name":"Does a worktree prevent Claude from reading ~/.ssh or ~/.aws?","acceptedAnswer":{"@type":"Answer","text":"See our full guide on claude code worktree isolation for a detailed answer to: Does a worktree prevent Claude from reading ~/.ssh or ~/.aws?"}},{"@type":"Question","name":"Can I automate worktree creation and teardown in a CI pipeline?","acceptedAnswer":{"@type":"Answer","text":"See our full guide on claude code worktree isolation for a detailed answer to: Can I automate worktree creation and teardown in a CI pipeline?"}}]}

Claude Code Worktree Isolation: Containing the Blast Radius of Agentic Tasks

What a worktree actually does — and what it doesn't

Claude code worktree isolation is the practice of running agentic Claude Code sessions inside a dedicated Git worktree — a linked checkout of a repository at a specific branch — so that any file writes, deletions, or experimental changes the agent makes are physically confined to that directory tree and can be discarded with a single command. It is a filesystem-level containment strategy, not a security sandbox.

That distinction matters more than most teams realize. When Claude operates in a worktree, it cannot touch files in your main working tree without an explicit path traversal. Accidental overwrites to src/, rogue deletions of build artifacts, half-finished refactors that break other engineers' work — all of that stays contained. You review the diff, merge what you want, and tear down the worktree. Clean.

What a worktree does not do: it does not prevent Claude from reading your home directory. If your allow list is too broad — or if you haven't defined one at all — an agent running inside a worktree has the same access to ~/.aws/credentials, ~/.ssh/id_rsa, and ~/.npmrc as one running in your main checkout. A 2023 GitGuardian report found that secrets are accessed within four seconds of a compromised credential being exposed in a cloud environment. Worktrees slow down filesystem sprawl; they do not slow down credential reads. The threat model is different, and conflating the two is where teams get hurt.

There is also the branch problem. Worktrees are linked to a branch. If you forget to create a fresh branch before starting an agentic task, the agent's commits land on whatever branch that worktree tracks — potentially main. Always pair worktree creation with an explicit branch checkout.

Setting Up a Throwaway Worktree Workflow

The baseline setup in four commands

The mechanics are straightforward. From your repository root:

git worktree add ../my-repo-agent-task -b agent/task-$(date +%Y%m%d-%H%M%S)
cd ../my-repo-agent-task
claude --allowedTools "Read,Edit,Write,Bash(git *),Bash(npm test)"

... run your agentic session ...

cd ..
git worktree remove my-repo-agent-task
git branch -d agent/task-20240614-143022

A few things are worth being explicit about here. The branch name includes a timestamp so you never accidentally reuse one. The worktree lives in a sibling directory rather than a subdirectory — this prevents Claude from accidentally resolving relative paths back into your main tree. And the worktree is removed immediately after the session, not left around "just in case." Stale worktrees accumulate and become invisible attack surface.

If you're running multiple agentic tasks in parallel — which is increasingly common on larger codebases — each task gets its own worktree on its own branch. This is actually one of the strongest arguments for this workflow: it makes parallelism safe by construction. Two Claude sessions cannot step on each other's file writes because they're operating in separate directory trees.

Scripting teardown so it actually happens

The failure mode in practice is that engineers run the session, get distracted by the output, and never tear down the worktree. Write a wrapper script that handles creation, invokes Claude, and tears down on exit — including on interrupt signals. Something like:

!/usr/bin/env bash

set -euo pipefail
BRANCH="agent/task-$(date +%Y%m%d-%H%M%S)"
WORKTREE="../$(basename "$PWD")-${BRANCH//\//-}"
git worktree add "$WORKTREE" -b "$BRANCH"
trap "git worktree remove --force '$WORKTREE' && git branch -D '$BRANCH'" EXIT
cd "$WORKTREE"
claude "$@"

The trap on EXIT means teardown happens even if Claude errors out, even if you hit Ctrl-C. This is not optional hygiene — it is the difference between a worktree workflow that works and one that leaves stale branches accumulating across your team's machines.

Combining Worktrees with Scoped Allow Lists

Allow lists do the work that worktrees can't

Worktrees contain writes. Allow lists contain reads and external calls. You need both. Running Claude in a worktree without a scoped allow list still gives the agent the ability to run arbitrary shell commands, read files anywhere on your filesystem, and make outbound network requests. For most production use cases, that's too much.

A reasonably tight allow list for a code-generation task looks like this in your project's .claude/settings.json:

{
"allowedTools": [
"Read",
"Edit",
"Write",
"Bash(git add )",
"Bash(git diff *)",
"Bash(git commit *)",
"Bash(npm test)",
"Bash(npm run lint)"
],
"deniedTools": [
"Bash(curl *)",
"Bash(wget *)",
"Bash(ssh *)",
"Bash(cat ~/.
*)"
]
}

The deny rules on curl and wget prevent data exfiltration via outbound HTTP. The deny on cat ~/.* * is a blunt instrument but catches the most obvious credential-read patterns. These are not foolproof — a sufficiently determined or confused agent can find other paths — but they dramatically narrow the surface area.

Pair this with a file-path restriction that pins Read and Write operations to the worktree directory. Claude Code's allowedPaths configuration (where supported) lets you specify that file operations must stay within a given prefix. Set it to the worktree's absolute path.

At CLaude coe, we've found that teams who combine worktree isolation with scoped allow lists catch the majority of agentic overreach before it causes damage. Neither control alone is sufficient. You can read more about our recommended configuration approach in the CLaude coe documentation, which covers allow list construction, deny rule patterns, and audit logging in depth.

A 2024 analysis by researchers at Carnegie Mellon found that agentic AI systems performing code tasks wrote to an average of 3.7x more files than the task strictly required when operating without path constraints. Worktrees bound the geography; allow lists bound the scope.

When Worktrees Are Not Enough

The cases that require a real container boundary

Worktrees are a Git construct. They share your kernel, your network stack, your user account, and your filesystem outside the worktree directory. For most internal development workflows, this is acceptable. For three specific scenarios, it is not.

First: when you're running Claude against untrusted code. If you've pulled a third-party repository and you're asking Claude to analyze or modify it, that code could contain prompt injection payloads — strings designed to redirect Claude's behavior. A 2024 study of open-source repositories found prompt injection patterns in build scripts and README files specifically targeting AI coding assistants. A worktree does nothing to contain a prompt injection; only evaluation-time controls can catch that.

Second: when compliance requires network isolation. Financial services, healthcare, and defense contractors often need to demonstrate that no outbound data transfer occurred during an agentic session. You cannot make that claim with a worktree. You need a container with a dropped network namespace or an explicit egress deny rule at the firewall level.

Third: when multiple agentic sessions are running with different trust levels on the same machine. A worktree offers no inter-process isolation. Two Claude sessions can read each other's worktrees trivially. If you're running a high-trust session (with access to production config) alongside a low-trust session (analyzing user-submitted code), they should be in separate containers with separate credential stores.

The practical threshold: if the task could result in code running with network access or reading secrets that you wouldn't want exfiltrated, use a container. Docker with --network none and a volume mount restricted to the worktree path gets you there with reasonable overhead. For teams that need a repeatable, auditable setup, the CLaude coe product overview covers our sandboxing recommendations and how we approach layered containment for agentic workloads.

Worktrees are the right tool for 80% of agentic coding tasks. They're fast to set up, have zero infrastructure dependency, and the cleanup story is simple. For the other 20%, don't convince yourself that a Git construct is a security boundary — it isn't designed to be one.

FAQ

Does a worktree prevent Claude from reading ~/.ssh or ~/.aws?

No. A Git worktree is a filesystem-level checkout, not a process sandbox. Claude running inside a worktree has the same read access to your home directory as any other process running under your user account. To prevent credential reads, you need explicit deny rules in your allow list configuration — specifically denying Read on paths like ~/.aws, ~/.ssh, and ~/.config — or a container with a restricted filesystem mount that physically excludes those paths.

Can I use worktrees with Claude Code's --dangerously-skip-permissions flag?

Technically yes, but you should not. The --dangerously-skip-permissions flag disables all tool confirmations, which means Claude can run any Bash command, read any file, and make any network request without prompting. Pairing this with a worktree creates a false sense of containment — the worktree bounds file writes to one directory, but unrestricted Bash execution means Claude can still exfiltrate data, install packages, or modify system state outside the worktree. If you need uninterrupted agentic runs, configure a tight allow list instead of disabling permissions entirely.

Can I automate worktree creation and teardown in a CI pipeline?

Yes, and for CI use cases this is the recommended approach. CI runners are already ephemeral, so the teardown story is simpler — the runner itself is discarded after the job. The setup is the same: create a branch, attach a worktree, run the Claude session, and commit or discard the diff based on your pipeline logic. The main CI-specific consideration is parallelism: if your pipeline spawns multiple Claude sessions against the same repo checkout, each must have its own worktree on its own branch. Shared worktrees across parallel jobs will produce merge conflicts and unpredictable file state.

Is a worktree safer than a Docker container for Claude Code tasks?

They solve different problems. A Docker container gives you process isolation, network isolation, and a controlled filesystem root — you can prevent Claude from seeing your home directory, block all outbound traffic, and limit the available binaries. A worktree gives you none of that; it only contains Git-tracked file changes to a single directory. Containers have higher setup overhead and require Docker or a similar runtime. For sensitive tasks — anything involving secrets, network access, or untrusted input — use a container. For routine code generation and refactoring tasks on internal codebases, a worktree with a scoped allow list is faster and sufficient.

What happens to uncommitted changes in a worktree if I force-remove it?

They're lost. git worktree remove --force deletes the worktree directory without checking for uncommitted changes. If Claude made useful modifications that you haven't committed or stashed, they're gone. Always run git -C <worktree-path> status before teardown, or commit everything to the branch before removing the worktree. For automated teardown scripts, consider adding a git stash before the remove command if you want a recovery option — though for throwaway tasks, loss of uncommitted work is usually the intended behavior.

Top comments (0)