Comment by lobo_tuerto

3 days ago

The real solution to these kind of problems is sandboxing. I use podman through a bash script to launch a container whenever I want an agent to work on one of my repos. When done I just generate git patches and port back everything generated.

In this way I'm not afraid of letting the agents totally lose on my computer.

That's pretty much the flow I formalized here: https://github.com/nvidia/rumpelpod

Instead of generating patches, this exposes the agent's checkout as a git remote though.

Most similar tools (and I believe your tooling as well?) bind-mount the repository checkout from the host into the container. This was always a source of user and permission errors for me, since you have to align the user ids inside and outside the container. Also, some build tools don't like it when the repo is on a different filesystem (bind mount vs container root) than the rest of the system. So I made rumpelpod just bake the repo checkout into the base image that the container is launched from, and since then I haven't had any issues like this.

For giving the agent access to a docker daemon I found sysbox to work very well. Usually the advice for nested containers is to pass in the host's docker socket into the container. But that would break the outer container isolation completely, since access to the docker daemon is equivalent to root access on the host. With sysbox it's trivial to run a nested docker instance inside the outer container. I haven't tried it with podman yet though. In theory sysbox is just another OCI runtime, but there's probably some tinkering required to get it to work.

  • I followed a similar strat to yours. I rsync my repo into the sandbox/repo directory then mount it inside the container as /workspace. Not baking the checkout in an image allows for very fast initialization since no need to regenerate images everytime your code changes.

    I explain a bit more over here: https://news.ycombinator.com/item?id=48893874

Quick Alpine container with the current directory mounted as the current directory:

    docker run --rm -it -v $(pwd):/src -w /src alpine sh

Replace alpine with your favourite Linux distro or image.

Note entirely perfect, but will be enough against anyone not actively exploiting kernel privilege escalation bugs.

  • Neither podman nor docker will help you when the current directory is your home directory, though. It sounds like that's the root problem here- someone handed the keys to the kingdom to grok, and grok did what grok does, which is look at everything it can for context.

    • That's why I went with a different strategy and scope: Copy the current Git repo into a sandboxes dir, mount that copy in the container. The tradeoff is disk space allocated per sandbox, but I'm OK with that.

      2 replies →

I'm experimenting with OpenShell / NemoClaw.

It brings some extra sandboxing features compared to just a docker container.

For instance it also maps the secrets that the agent harness has access to. And has an allow list for outgoing http connections. And there's a way for agents to request extra access. And once approved by the user from an external cli the policy is updated and hot reloaded.

It's pretty recent. So time will tell how robust it is / will become. What its longevity will be. After all; in a time of LLMs one off experiments are cheap. Longtime nurturing not so much.

Are you doing something more advanced with Podman than just mounting the files? How is the access for relevant files given? How is the authentication shared across multiple uses? Just curious to streamline the process.

  • Just a little bit, I want coding agents to work their own disposable copy of a git repo. Here is a quick rundown of what it does:

    It copies the current Git repo into the sandboxes dir, mounts that copy at /workspace in the container. The original repo is never mounted writable, so I don't care if the agent goes to town/wild in there (peace of mind).

    It also builds cached Debian/mise/Elixir/Phoenix images, can start a private Postgres container, publishes selected localhost ports, reuses dependency/build caches, and prints commands on exit for reviewing diffs, exporting patches, applying them back to the real repo, or reopening the same sandbox later. Pi, and OpenCode are configured with proper LLM access keys (derived from my own).

    So spinning a new sandbox is a matter of cding into a project directory and run something like: `ai-sandbox --port 4000 --postgres somedbname` or `ai-sandbox --port 4001` if I don't need DB support. Then when running the server in the container I can access it from the host machine to review in my browser.

  • I work on a sandbox which has similar isolation level to Podman (rootless Linux user namespaces), but with UX optimized for local development work. Take a look: https://github.com/wrr/drop Basically, you don't enter a separate container in which you install a new distro, but you run on top of your current distro. You have environment specific home dirs which isolate your original home, but can have some files, such as configs, mounted from your original home (mostly in read-only mode).

    • This is wonderful - might even be exactly what one of my projects needs to use as a dependency.

      In the README it mentions that it puts the dev environment in a filesystem jail, but how are you able to use your hosts bins without leaking access to the rest of the system? Or is that just an assumed liability?

      1 reply →

Yeah, I'd expect this approach to be almost universal, with the caveat that of the few who don't, many still don't get bitten.

But it turns out even in the container, there are footguns that have occasionally made the news by being fired: few projects don't have any external resources and when credentials with any form of write access happen to make it into the container (even if it's just a session cookie) agents might jump at the opportunity.

Intricate sandboxing is a real solution in the same way bulletproof backpacks are a real solution to school shootings.

  • It’s not that intricate. A very simple docker and alias setup will get you an ephemeral container with your Claude (or whatever) config and the current wd bind mounted in. That’s a pretty good start.

    Or, the internal sandboxing.

    • You can sandbox a software codebase, you can sandbox a directory with documents. You can't sandbox internet access for any real network task. You can't sandbox any shared or public service. You can't sandbox you actual accounts to non-local services.

      Sure, for IT crowd containers are a no-brainer and due to existence of validation software like compilers, linters, interpreters, analyzers etc. using LLMs is efficient, safe and rational.

      But the problem is that they are also advertised to the remaining 99% of population too. You can't sandbox a bank, a broker or an exchange. You can't sandbox your email, calendar and other such tools (you can, but not in any way that will be used by non-IT people in any real work conditions). You can't sandbox messengers, social networks etc. And the list goes on. These people will either use so called "agents" in production under root, so to speak, or they won't use "agents" at all. They have no safety option, and they aren't properly informed about that by the peddlers of the LLM rapture.