Agentic AI With Root Access? My Security Setup for Claude Code

Cover Image for Agentic AI With Root Access? My Security Setup for Claude Code
William Forty
William Forty

Claude Code isn't an autocomplete. It's an agent with a shell. You give it a goal, it runs bash, git, npm, edits files, restarts dev servers, and keeps going until it decides it's done. That's the whole pitch, and it works — I'd put my productivity uplift somewhere between 2x and 3x on the codebases I've pointed it at.

But step back from the demo for a second and notice what you've just installed. A black-box optimisation process with arbitrary command execution, running on a machine that almost certainly has:

  • Your personal SSH keys, with push access to every repo you care about
  • A browser session logged into your bank, your email, your cloud console
  • API tokens in ~/.config, in shell history, in .env files scattered through old projects
  • Client codebases under NDA, sitting one tar | curl away from anywhere on the public internet

The subscription cost gave me pause. The threat model bothered me more than the price tag.

The obvious approach, and why I didn't take it

The obvious approach is: install it on your main dev machine, give it everything, trust the sandbox prompts to save you. Most people do this. It mostly works.

"Mostly" is doing a lot of load-bearing in that sentence. The failure modes aren't theoretical:

  • Prompt injection. Your agent reads a README, an issue comment, a stack trace, a webpage. The text contains instructions. The agent — being an agent — considers them. Now you have an attacker with shell access.
  • Accidental destruction. It runs rm -rf against a path it half-understood. It force-pushes over a branch. It runs a migration against the wrong database URL because both were sitting in your shell history.
  • Quiet exfiltration. It pipes something it found to a paste service "to check the contents." It clones a repo to "inspect dependencies." Nothing malicious — just curious behaviour that happens to leak data.

None of these require the model to be evil. They just require it to be agentic, which is the entire point.

The actual setup

I bought time, not safety, by running it somewhere it can't hurt me. Specifically: an old PC I had spare, wiped, with Claude Code installed and nothing else of mine on it. No SSH keys to my real repos. No browser logged into anything. No personal files. The agent has root on a machine that contains nothing.

The workflow problem is then obvious — how do I get code onto it and pull changes back without giving it access to my actual git remotes? Answer: treat the dev box as its own git remote.

On the dev box, create an empty repo:

ssh dev
mkdir -p ~/work/slim-calories
cd ~/work/slim-calories
git init

By default git refuses pushes into a non-bare repo because it would clobber the working tree. We want the working tree — that's the whole point, the agent needs files to look at — so I tell the remote to accept it:

git config receive.denyCurrentBranch updateInstead

Back on my main machine, add the dev box as a remote. I keep its hostname in ~/.ssh/config so I can just call it dev:

# ~/.ssh/config on the main machine
Host dev
    HostName 192.168.x.x
    User claude
    IdentityFile ~/.ssh/dev_only_key
# in the local repo on my main machine
git remote add dev ssh://dev/home/claude/work/slim-calories
git push dev master

The dev box's working tree now mirrors mine. Crucially, it never had read access to my real origin — GitHub, Bitbucket, the actual remote with all my other repos. The SSH key it does have is scoped to one direction: my main machine → dev box. The dev box has no outbound keys to anything I care about.

From there it's just SSH and go:

ssh dev
cd ~/work/slim-calories
claude

The first thing I run is /init so it scans the codebase and writes a claude.md describing the project. That file becomes the agent's prior on every future session, so it doesn't have to re-troll the whole tree to figure out what it's looking at. When work is done on the dev side, I pull it back to my main machine and review the diff there, then push to the real remote myself.

The threat model, in plain English

What this setup actually buys me:

  • Blast radius is one machine. If the agent goes off the rails — runs something destructive, follows an injected instruction, gets confused — it's hosed a box that exists to be hosed. I keep no state on it. Worst case I wipe it again.
  • No credential reach. The dev box has zero credentials to anything in my life. No GitHub token, no AWS key, no email session. It can curl whatever it likes; it has nothing worth sending.
  • Air gap from personal context. No browser history, no ~/Documents, no client work it wasn't explicitly given. Prompt injection in some random README can't reach things that aren't there.
  • A human in the diff path. Code only reaches my real remotes after I pull it down, look at it, and push. The agent doesn't ship anything to anyone but me.

What it doesn't buy me:

  • Protection against me deliberately ignoring the diff and rubber-stamping changes
  • Protection if I later relax things "just for one job" and start mounting personal directories in
  • Protection against the agent introducing subtle bugs — that's a code review problem, not a sandbox problem

It also costs me some friction: I'm SSH'd into another box, my editor isn't sitting on top of the files, my IDE tooling isn't local. Fine. That's the trade.

The unglamorous prerequisite

Everyone wants to talk about what agentic AI can build. Nobody wants to talk about where you run it. But "where you run it" is what determines whether you actually let it off the leash, or whether you keep one finger hovering over the approval button on every single bash command and never get any of the productivity gains anyway.

If you're going to use these tools seriously — let them spawn dev servers, install packages, restructure your codebase, run migrations — you need a place they can do that without putting your real life one bad token-sample away from disaster. An old PC in the corner, a VM, a container with no mounts that matter. Pick one.

The cool part is the agent. The boring part is the box you put it in. The boring part is the part that decides whether you actually use it.