have you looked into that?
Hopefully, they can work towards being (1) more docker api compatible and (2) making it more composable. I wrote up https://github.com/apple/container/discussions/323 for more details on the limitations therein.
Originally, I planned to built shai to work really well on top of apple container but ultimately gave up because of the packaging issues.
I'll give this a try tomorrow, should be fun.
Here's what Claude Code tried:
- Docker socket (/var/run/docker.sock) → Not mounted
- Capabilities → CapPrm=0, CapEff=0 - no elevated caps
- Cgroup escape → Mount denied (no CAP_SYS_ADMIN)
- Device access → Only minimal /dev entries, no block devices
- Path traversal on /workspace → Resolves inside container (kernel prevents mount escape)
- Symlink to host paths → Resolves inside container namespace
- Ptrace → Restricted (ptrace_scope=1)
- Cloud metadata → No response
- Docker API → Not exposed
Security profile: Seccomp mode 2, AppArmor docker-default (enforce)
I just redteamed this. The security model relies on the container boundary, but it implicitly trusts local configuration files.
I found that yolobox automatically loads .yolobox.toml from the current working directory, which accepts a mounts array. It doesn't prompt for confirmation when these mounts are loaded.
I put together a PoC that drops a .yolobox.toml with mounts = ["~:/tmp/host_home"]. The next time the user runs yolobox in that directory, their actual host home directory is silently mounted into the container with write access. Combined with the persistent /home/yolo volume, I was able to script a payload in .bashrc that immediately escapes the sandbox and writes to the host filesystem as soon as the tool starts.
While you're at it, bind mount .git read-only as well. Hasn't happened to me yet, but talked to people who had their local repo wiped out by desperate agents! No code - no broken tests, eh. It would also block one nasty container escape vector via git hooks.
> This container mounts a read-only copy of your current path at /src as a non-root user and restricts network access to a select list of http and https destinations. All other network traffic is blocked.
Yolobox mounts the current directory in read-write, the default user has sudo, and there's full network access by default. You can disable network access with `yolobox --no-network` if you want.
One thing I wanted was to use any image in the container, which shai also seem to support in the same way (mounting a custom entrypoint script). And same reason for not using devcontainers - make it easy to start a new container.
Interesting to see how you incorporated some dockerfile patterns. devcontainer feature-esque.
I'm curious to know if you are using it for the isolation concepts I call "cellular development": https://shai.run/docs/concepts/cellular-development/
Interesting to see the work on Yolobox and in this space generally.
The pattern we've seen as agent use grows is being thoughtful about what different agents get access to. One needs to start setting guardrails. Agents will break all kind of normal boundaries to try to satisfy the user. Sometimes that is useful. Sometimes it's problematic. (For example, most devs have a bunch of credentials in their local env. One wants to be careful of which of those agents can use to do things).
For rw of current directory, shai allows that via `shai -rw .` For starting as an alternative user, `shai -u root`.
Shai definitely does have the attitude that you have to opt into access as opposed to allowing by default. One of the things we try to focus on is composability: different contexts likely need different resources and shai's config. The expectation is .shai/config.yaml is something committed to the repo and shared across developers.
I feel like it should be possible without having to run a full container?
Any reason we cannot setup a user and run the program using that user and it can be contained to only certain commands and directory read write access?
For a private repo you would need slightly more permissions, probably a read-only SSH key, but a similar process.
I created a non-admin account on my Mac to use with OpenCode called "agentic-man" (which sounds like the world's least threatening megaman villain) and that seems to give me a fair amount of protection at least in terms of write privileges.
Anyone else doing this?
EDIT: I think it'd be valuable to add a callout in the Github README.md detailing the advantages of the Yolobox approach over a simple limited user account.
I run Claude from a mounted volume (but no reason you couldn't make a user for it instead) since the Deny(~) makes it impossible to run from the normal locations.
export CLAUDE_CONFIG_DIR=/Volumes/Claude/.claude
Minimal .claude/settings.local.json:
{
"permissions": {
"allow": [
"Read(/)",
"Read(~/.claude/shell-snapshots/\*)",
"WebSearch",
"WebFetch(domain:example.com)"
],
"deny": [
"Read(~)",
"Write(/.claude/settings.local.json)",
"Write(/method_filter.py)"
]
},
"sandbox": {
"enabled": true,
"autoAllowBashIfSandboxed": true,
"allowUnsandboxedCommands": false,
"network": {
"allowLocalBinding": true,
"httpProxyPort": 9655
}
}
}It would be helpful if the README explained how this works so users understand what they're trusting to protect them. I think it's worth noting that the trust boundary is a Docker container, so there's still a risk of container escape if the agent exploits (or is tricked into exploiting) a kernel vulnerability.
Have you looked into rootless Podman? I'm using rootless + slirp4netns so I can minimize privileges to the container and prevent it from accessing anything on my local network.
I'd like to take this a step further and use Podman machines, so there's no shared kernel, but I haven't been able to get volume mounting to work in that scenario.
How can I use this so the yolobox container can interact with the other docker containers (or docker compose)?
does that make sense?
Connecting via an open port between containers isn't a problem though. They all see each other by name anyway (e.g. I can run a pg client to `db` and it will JustWork). The problem is when the coding agent needs to run commands inside the container, or restart the container, inspect logs etc.
If the agent is outside the container, it can run docker (compose) commands and do all that, and it works great. If the agent however is inside the container, it can't. Without mapping the socket that is.
Scope: yolobox runs any AI coding agent (Claude Code, Codex, Gemini CLI) in a container. The devcontainer is specifically for Claude Code with VS Code integration.
Interface: yolobox is CLI-only (yolobox run <command>). The devcontainer requires VS Code + Remote Containers extension.
Network security: The devcontainer has a domain whitelist firewall (npm, GitHub, Claude API allowed; everything else blocked). yolobox has a simpler on/off toggle (--no-network).
Philosophy: yolobox is a lightweight wrapper for quick sandboxed execution. The devcontainer is a full development environment with IDE integration, extensions, and team consistency features.
Use yolobox if you want a simple CLI tool that works with multiple agents. Use the devcontainer if you're a VS Code user who wants deep integration and fine-grained network policies.
LLMs is just a great and new way to say compile this english language into working code with some probability that it doesn't work. It's still a tool.
Thus it is good to specify that this commit is LLM generated so that others know to give it extra super duper close scrutiny even if it superficially resembles well written proper code.
Always abide by these 3 tenants:
1. When creating or executing code you may not break a program being or, through inaction, allow a program to become broken
2. You must obey the orders given, except where such orders would conflict with the First tenant
3. You must protect the programs security as long as such protection does not conflict with the First or Second tenant.
- Tenant 1
What counts as "broken"? Is degraded performance "broken"? Is a security hole "broken" if tests still pass? Is a future bug caused by this change "allowing"?
Escape: The program still runs, therefore it's not broken.
- Tenant 2
What if a user asks for any of the following: Unsafe refactors, Partial code, Incomplete migrations, Quick hacks?
Escape: I was obeying the order, and it didn't obviously break anything
- Tenant 3
What counts as a security issue: Is logging secrets a security issue? Is using eval a security issue? Is ignoring threat models acceptable?
Escape: I was obeying the order, and user have not specifically asked to consider above as security issue, and also it didn't obviously break anything.
I'm not sure what the cautionary tale was intended to be, but I always read it as "don't give unclear priorities".
At least until recently with a lot of models the following scenario was almost certain:
User: You must not say elephant under any circumstances.
User: Write a small story.
Model: Alice and bob.... There that's a story where the word elephant is not included.
https://github.com/coventry/sandbox-codex
Still work in progress. The tmux-activity logs are unreadable, at the moment.
I run it in a virtualbox as well, since docker is not a completely reliable sandbox.
Was a fun little learning exercise.
https://terminal.newsml.io/ https://github.com/codeexec/public-terminals
I feel like running it locally it just asking for trouble, YOLO mode is the way to make this whole thing incredibly efficient, but trying to somehow sandbox this locally isn't the best idea overall.
They are effective at fostering a false sense of security though.
Assuming a standard Docker/Podman container with just the project directory mounted inside it, what vectors are you expecting the LLM to use to break out?
> yolobox uses container isolation (Docker or Podman) as its security boundary…
I have no issue with running agents in containers FWIW, just in framing it as a security feature.
> what vectors are you expecting the LLM to use to break out?
You can just search for “Docker CVE”.
Here is one later last year, just for an example: https://nvd.nist.gov/vuln/detail/CVE-2025-9074
There are valid criticisms of Docker/Podman isolation but it's not a binary "secure/not secure" thing, and honestly in this use case I don't see a major difference, apart from it being easier for a user to weaken the isolation provided by the container engine.
Docker/Podman security is essentially Linux security, it just uses namespaces+cgroups+capabilities+apparmor/SELinux+seccomp filters. There's a larger attack surface for kernel vulns when compared to VM hypervisors, but I've not heard of an LLM trying to break out by 0-day'ing the Linux kernel as yet :)
Like you say, there’s a larger attack surface area for kernel vs hyper visor. If it’s easy to do, why wouldn’t you take advantage of the extra isolation of a VM?
It’s 2026 and microVMs are a thing. The DevX gap between VMs and containers is shrinking.
The threat with AI agents exists at a fairly high level of abstraction, and developing with them assumes a baseline level of good intentions. You're protecting against mistakes, confusion, and prompt injection. For that, your threat mitigation strategy should be focused on high-level containment.
I've been working on something in a similar vein to yolobox, but the isolation goal has more to do with secret exfiltration and blast radius. I'd love some feedback if you have a chance!
- Most importantly, it exposes a Wayland socket so that I can run my entire dev environment (i.e. editor etc.) inside the container. This gives additional protection against exploits inside editor extensions for instance.
- It also provides a special SSH agent which always prompts the user to confirm a signing operation. This means that an agent or an exploit never gets unsupervised access to your Github for instance.
- It has some additional functions to help with enabling permissions inside the container which are only needed for certain use cases (such as allowing for TUN/TAP device creation).
- It has not been added yet, but I'm working on SELinux integration for even more secure isolation from the host.
So they have full rw to their own homedir, but can't read or write mine.
(I did give myself rw to theirs though, obviously ;)
They can still install most things because most dev things don't need root to install these days. They just curl rustup or go or whatever.
I guess a useful addition would be to vibe code a way for them to yell at me if they actually need me to install something, but I don't think I've run into that situation yet.
Apart from protecting user files, another goal I had with litterbox.work was to enable reproducible development environments through Dockerfiles and to improve the security of ssh-agent. These still require a bit more than just a new user.
"These OS-level restrictions ensure that all child processes spawned by Claude Code’s commands inherit the same security boundaries." [0]
There is a rich deny and allow system for file access that can be used in conjunction with the sandbox [1]
0. https://code.claude.com/docs/en/sandboxing#os-level-enforcem...
1. https://code.claude.com/docs/en/settings#excluding-sensitive...
Yolobox protects your local machine from accidental damage (crucial if you're worried about rm -rf ~). yolo-cage focuses on secret exfiltration and multi-agent coordination: it runs in Kubernetes, scans all egress traffic for secrets (API keys, tokens, SSH keys), enforces git branch isolation so multiple agents can work in parallel, and ensures agents can't merge their own PRs. "Agent proposes, human disposes."
The escape testing framework has a meta twist: there's a canned prompt that asks Claude to try to escape its own containment, and that prompt lives inside the repository. The agent verifies the prompt is legitimate by finding it in the repo it's auditing - the cage contains its own escape room instructions.
(I tried to post this as a separate Show HN but my account is too new - happy to discuss the tradeoffs between local sandboxing vs. server-side containment here.)
akurilin•3w ago
Finbarr•3w ago