Repository navigation
blog/coding-agents-in-secured-vscode-dev-containers #7
Replies: 7 comments 21 replies
Devcontainers is a standard with specs: https://github.com/devcontainers/spec/tree/main/docs/specs And VS Code has a long page about their implementation: https://code.visualstudio.com/docs/devcontainers/containers But I couldn't find the SSH forwarding and IPC sockets features properly documented in either. So unfortunately this means it's a moving target, so I'll ask Claude to try to break out every now and then 😅 unless you have a better idea? But in any case, this setup will be incomparably more secure than running on the host or vanilla container anyway! |
|
Thanks for a great writeup. It has helped me finalise my own sandboxed Claude. I even wrote a skill that points at your blog and asks Claude to try and break out using your info! I'm rootless with podman and have managed to make it so that users terminals get all the ssh key and git cred goodness but Claude gets none of the creds. I also added GH cli PAT for Claude so it can write PRs and look at CI for me but not force push, change workflows or see any repos other than what I give it. The approach to achieve this is removing access to sensitive folders and files using namespaces. That might also fly for rootful and avoids trying to delete socket files. BTW I'm pretty sure vscode creates a new IPC socket for every terminal so your 5 minutes loop may not be enough. If you are interested in my approach see gilesknap/python-copier-template. |
|
Awesome article! I share your enthusiasm for containerizing everything / doing all development inside devcontainers, but I don't share all the knowhow... so much appreciated for sharing! Based on a convo with claude, it seems like dropping 'VSCODE_IPC_HOOK_CLI' could lead to some degradation in claude's ability to integrate / interface with the editor -- does that track with your understanding and/or experience? Or have you been able to drop it with no noticeable loss? If there is a loss, I'm wondering if re-enabling could be possible, and then just my restricting the allowed extensions we could make the case it's still secure (if I'm correct the main attack vector there is registering arbitrary extensions). |
|
This makes me wonder if vscode should be ditched and I just learnt cop the
DevEx loss and use Helix.
…On Fri, 5 June 2026, 1:45 pm Parker M, ***@***.***> wrote:
I've been experimenting with some further devcontainer hardening,
specifically an environment where I don't want to disable container
creation (things run under the agent profile, as you'll see below), and
I've been using some claude code instances in devcontainers to try and
'escape'.
One instance just found: the env-scrub only unsets handles in shells (via
BASH_ENV). The long-lived claude process (uid 2000, readable by agent)
still carried VSCODE_IPC_HOOK_CLI=/tmp/vscode-ipc-…sock, recovered from
/proc//environ; all four host-bridge socket names are also enumerable from
world-readable /proc/net/unix. The env-scrub is therefore bypassable.
Why no crossing completed: the socket files are swept by the periodic
compose sweeper and only re-created transiently during VS Code activity.
So at least a pen-testing claude agrees with what @gilesknap
<https://github.com/gilesknap> is mentioning, that those vscode sockets
could be created at any moment, at will by vscode.
—
Reply to this email directly, view it on GitHub
<#7?email_source=notifications&email_token=AEMCKXAYN2PUBLQ4XHCR6CL46I67HA5CNFSNUABIM5UWIORPF5TWS5BNNB2WEL2ENFZWG5LTONUW63SDN5WW2ZLOOQXTCNZRHA3TQNRWUZZGKYLTN5XKO3LFNZ2GS33OUVSXMZLOOSWGM33PORSXEX3DNRUWG2Y#discussioncomment-17187866>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEMCKXGUZJVXQZVWCDSIUUT46I67HAVCNFSM6AAAAACXFBH2ZSVHI2DSMVQWIX3LMV43URDJONRXK43TNFXW4Q3PNVWWK3TUHMYTOMJYG44DMNQ>
.
You are receiving this because you were mentioned.Message ID:
***@***.***
com>
|
|
So I decided that I was also worried about lateral network egress because a rogue agent inside your LAN could still potentially find some attack surfaces without any credentials. https://gilesknap.github.io/claude-sandbox 2.0 has network isolation via a userspace pasta network with restrcted routing. Like the filessystem isolation you can open up IP addresses explicityly if you want the agent talking to a device. This is for your LAN only and still allows egress to the internet. If you want to limit internet access you have claude's built in sandbox for that. Sorry to keep spamming your discussion talking about my project! I can't find anyone else on the internet actively discussing this issue. I tried to get some discussion going on reddit, but there does not seem to be huge uptake. https://www.reddit.com/r/ClaudeAI/comments/1qimfr0/comment/osiukhm/?context=3 Any links to useful discussion on this topic would be appreciated. |
|
Hi! Do you know how the environment variables pointing to the sockets are set ? I tried to just read them in postAttachCommand and they seem empty at this stage. My goal was to remove any existing socket and create a read-only file in its place to prevent later creation. If they are dynamically update this won't work obviously, but I've never even heard about setting env vars dynamically. |
|
Sorry for going quiet on this thread for so long – I've been busy building a new solution (and preparing a conference workshop about it) inspired by the discussions! @nlgranger as far as I can tell those variables aren't set container-wide: the VS Code server injects them into the processes it spawns (each integrated terminal, tasks, the extension host), which is why they're empty in
@p-buddy in my experience unsetting @gilesknap thank you again – rootless Podman was the nudge that sent me down this path, and you were right about the per-terminal sockets. On lateral movement: I went with a firewall inside the VM that refuses any direct connection apart from DNS and the proxy on the host, so the sandbox can't reach the LAN by itself. The weak spot is the proxy: it runs on the host and judges requests by hostname only. With the allowlist enforcing, a LAN address is refused unless you grant it – but during the initial learning window, or via an allowlisted hostname that resolves to an internal IP (DNS rebinding), it would connect to the LAN on the sandbox's behalf. Refusing loopback/private/link-local destinations at the proxy by default is next on my list, and I'd love to compare notes on how you handle it with pasta. @stevenhuyn @gilesknap on Zed: I looked into it too, but when I checked in June its remote development was SSH-only, which would mean running So, without any further ado: meet Foldyard, an open source tool that runs your project's whole dev stack (compose services, installs, IDE backend and the agent) in a separate Lima VM per project that mounts only the repo, on rootless Podman. Credentials stay on your computer: a proxy there adds scoped tokens (short-lived ones where the service supports minting them) to outgoing requests, so the sandbox never holds them. Edit: corrected what I said about LAN access and what |
Uh oh!
There was an error while loading. Please reload this page.
I was initialy drawn (misguidedly) to dev containers for their security. And have since been looking for a nice solution.
Have you noticed needing to update the configuration as vscode updates? Or is the devcontainer + vscode implementation very stable here.
All reactions