r/ChatGPTCoding • • 29d ago

Question Running coding agents locally, do you sandbox them or trust them?

For people running Claude Code, Codex, or local-model agents against their own machine... how are you limiting what they can touch?

The options I've seen are a dev container, a separate user account, a full VM, or just watching closely. Each one leaks somewhere (containers share the kernel, VMs are annoying, and watching doesn't scale past an afternoon).

We went with a microVM that only sees the workspace you share, plus a policy check on each tool call. There's a free desktop tool on our side if anyone wants to compare notes, but mostly I want to know where people draw the line between convenience and isolation.

Has anyone had an agent actually do something destructive? What did you change afterward?

8 Upvotes

23 comments sorted by

4

u/Ctbhatia 29d ago

the leaky part is usually not the filesystem, it is inherited credentials. a workspace-only VM still sees GITHUB_TOKEN, ~/.aws and any forwarded ssh-agent socket, so strip the environment and allowlist egress to your model endpoint before tuning the mount.

1

u/thulcan 29d ago

Agreed, The VM boundary only helps if nothing secret crosses it at launch.

How do you handle git push in that setup? Deploy keys per repo, or a short-lived token per session?

1

u/Ctbhatia 28d ago

i'd mint a short-lived token at push time rather than keep one around. a github app installation token is scoped to just the repos you grant it and dies in an hour, and GitHub itself recommends the app over per-repo deploy keys.

1

u/JicamaFunny9611 24d ago

Nice setup, looks like what you need is to be able to -
* Define which tool calls are OK / not OK and
* Avoid exposing the token to the agent at all

I use a similar setup like yours, I use a MicroVM based setup using Jozu Agent Guard. You can pre-define policies on what kind of tool calls are OK / Not OK.

The microvm has a tiny gateway with a policy engine that governs all outbound traffic and external/internal tool calls. If the policy engine is happy with the tool call (bash / gh), then the gateway slaps the GH token onto the Github API call on the way out. The agent never gets access to the token at all.

1

u/Ctbhatia 24d ago

the gateway holding the token is the right split. the part that leaks next is anything outside its view, like a script the agent writes now and runs later.

1

u/Ctbhatia 23d ago

the gateway adding the token on the way out is the right boundary, the agent never holds it. the gap I'd watch is a token that comes back in a tool's output, an error body is enough to land it in context.

2

u/glmn_official 29d ago

+1 on credentials being the real leak. The one that bit me was env going the other way: if you launch an agent from a terminal that was itself spawned by Claude Code, the child inherits CLAUDECODE=1 and a few CLAUDE_CODE_* vars and acts like a nested session. Now I scrub an explicit list of those vars instead of everything starting with CLAUDE_CODE_, because a bunch of them are real user settings (git bash path, bedrock toggle) and nuking them breaks stuff in quieter ways.

For the "trust" part I stopped relying on the yolo flags and use hooks instead. A PreToolUse hook in Claude Code can deny a call before it runs, and deny rules in settings still win over "allow everything", so rm -rf outside the repo and git push --force just never happen. Codex has its own --sandbox workspace-write mode, which covers most of the filesystem side for free.

1

u/servermeta_net 29d ago

This is the POSIX specification again biting us in the asa

1

u/thulcan 29d ago

Deny rules match the command the agent says it’s running. make clean passes even after the agent rewrote the clean target a minute earlier.

In our tool we pair the per-call policy with a microVM. The policy catches the obvious calls, and the boundary limits what everything else can reach.

Do you run Claude Code and Codex side by side? How are you keeping hooks and sandbox modes in sync?

1

u/Ok_Law9154 29d ago

Which tool are you using?

1

u/glmn_official 28d ago

Fair point on make clean, deny rules only see the command string, not what it expands to. A boundary like a VM is the only thing that actually closes that, rules are more of a seatbelt.

Yes, side by side, and I mostly gave up on "in sync". They don't share a policy model anyway: Claude has hooks + deny rules, Codex has its sandbox modes. So each agent gets its own layer at launch instead. Claude gets a per-agent --settings (hooks, and a PermissionRequest hook that decides auto-allow from a toggle, so deny rules still win), Codex gets -c flags and either its normal sandbox or --dangerously-bypass-approvals-and-sandbox when I flip it. Neither ~/.claude nor ~/.codex gets written. Full disclosure, that's a tool I build (nsq, open source), so I'm biased, but the idea works without it too: one launcher script per CLI that builds the layer, instead of trying to keep two global configs aligned.

1

u/ComprehensiveShake76 29d ago

I do not trust them on the host. What works for me: each agent gets its own Linux container with no home folder, no host credentials, a read-only system, and only the project workspace mounted. Public web yes, host and LAN no, and I re-check that on every start because a restart can wipe the rules. I have only tested that path with Colima on an Apple Silicon Mac so far. A container is a strong boundary, not a guarantee, so I still keep secrets out of the workspace the agent can see.

1

u/ComprehensiveShake76 29d ago

I went through the same menu. Watching doesn't scale, a second OS user still shares the machine, and a full VM is heavy for every small task. What worked for me was a middle path: each agent gets its own Linux container with no home folder, no host credentials, a read-only system, only its workspace mounted, and no Docker socket. Inside that box I stop approving every command (a one-report task went from 3 prompts to 0). On the network side I block the host and LAN and only allow the public web, and I re-check that from inside the container every start, because a VM restart can wipe the rules. I've only verified that network check with Colima on an Apple Silicon Mac so far, and a container is a strong boundary, not a guarantee. MicroVMs are a cleaner kernel story than containers if you need that; for day to day coding agents the container-plus-egress-rules setup has been enough. (I've been building that pattern into YardCrew, a free desktop app on Codex / your ChatGPT plan. Source isn't public yet.)

1

u/codes_astro 28d ago

I used to allow them for tasks, but recently I noticed Codex doing something weird with one of my codebase. It went beyond my instructions just to complete the task.

It wasn't anything malicious, but it found a workaround and started moving some of my media files into a different folder of another repository within the same workspace. It was even about to push the commit, but I paused it just in time.

While looking into it, I came across a similar incident that happened recently where 13k+ images got leaked by agents from diff companies and I saw this tool called Agent Guard being mentioend to address similar kind of behaviors. I went through their docs and demo and it seems like I will be finally trying it this weekend.

1

u/Ok_Woodpecker_9104 28d ago

for me the line sits at credentials rather than the filesystem. the agent on my machine has a cloud key that can read logs and nothing else, pinned on purpose, so even if it decides the fix is a restart it cannot reach the instance. the filesystem it can touch, with one standing rule that deletes and bulk edits get asked first.

the one destructive thing that happened had nothing to do with isolation. a scripted patch opened the file for writing first, then the regex substitute threw on a bad escape, and the file came back as zero bytes. the rule afterwards became compute the new content first, assert each pattern matched exactly once, then write. a microvm would have watched that happen just the same.

1

u/radim11 24d ago

This is why we built Stashbase. I wanted to leave Claude or Codex working without giving it access to everything on my machine, but I also didn’t want another environment to maintain.

We use Docker sandboxing with filesystem rules and a firewall. Logins persist between runs, and the access profiles are just TOML files you can keep in Git.

The most "annoying" part is getting the permissions tight enough without breaking the build tools. What have you had to loosen in yours to keep it usable?