today at 7:45 PM
Every comment is talking about their own sandbox implementation.
today at 2:56 PM
Hi OP, funny enough Iām working on something very similar. Lots of us are I guess! Take that as validation of your thinking.
I like that your readme has a couple paragraphs comparing to popular tools in this space. Personally I feel it is a bit light on the security differentiators (if any). For example you are using the same fundamental primitives that are used in nsjail, runc, etc. Thus it seems you have recreated those libraries in some aspects, so would be curious to hear your rationale for approaching this way vs building explicitly on those primitives.
today at 3:36 PM
Thanks! My initial approach and the first prototype was for Drop to be a Python script that generates config.json file for runc Docker runtime (I also tried crun). I ran into issues that prevented the sandbox from being set up with all the Drop-required properties. These issues were certainly technically fixable, but it could be difficult for a new project with no usage to advocate for features in mature and widely adopted tools. Especially that runc and crun are OCI-compatible Container Runtimes, and Drop is not an OCI-compatible container, so it could be justifiably out of scope for these projects not to support Drop usage.
Anyway, my decision, for which I also evaluated the use of bubblewrap as a building block, was to err on the side of flexibility that calling fine-grained Linux APIs directly give. For a project like Drop, runc could be seen as very coarse-grained JSON-based API to Linux sandboxing calls (basically a single call: setup a sandbox, here is a json config that describes it), similarly bubblewrap is a coarse grained command-line API to Linux sandboxing calls. Reusing such tried and proved layers of course also has significant advantages, so as in case of many engineering decision, it wasn't super obvious which path is better.
Drop eventually integrated gVisor's runsc (as an option), which is also OCI-compatible Container Runtime, but this is to add a user-space kernel isolation layer.
today at 6:39 PM
So there are a lot of ad-hoc solutions everybody is using for agent isolation and Drop looks well thought out. But the obvious question is what do the pros use? What does Anthropic, OpenAI, SpaceXAI, Google and Amazon do in house to deal with the isolated agent environment problem?
Based on past experience I'm guessing everybody is using Kubernetes, but what are the details? Stripped down VMs on Kubernetes? Hardened containers on Kubernetes? Can the rest of us spin up something comparable on K3s?
Anybody knows the answers and can share?
today at 3:01 PM
This is super interesting to me. I've slowly been working on something similar (https://gitlab.com/saghm/tartarus) because my ideal sandboxing is "prevent writing to anything outside this dir but still allow reading to most things so that I don't have to manually copy things into a container/VM". I approached it by trying to figure out how to build up a bubblewrap based on a config that gave the properties I wanted, with the hope that I could eventually expand it to support other platforms via stuff like `sandbox-exec` on MacOS, but I haven't had time to work on it more for a while.
At a glance, this seems to be providing most of what I was originally looking for when I ended up deciding I'd have to write it myself, but focusing specifically on Linux and providing a more full-fledged sandbox rather than only caring about a small set of permissions that I personally had a need for. Probably the biggest (and least hardened) feature that I spent time on in mine was trying to figure out how to allow arbitrary GUI apps so that I could run agents in it via Zed.
I'm definitely going to try this out and see how well it works for me. It's insane to me that this is something none of the big AI companies have bothered solving this yet other than via opaque rules built into their harnesses or absolutely awful manual rules that expect me to hard-code shapes of shell commands that I want to allow or not allow.
today at 3:05 PM
> my ideal sandboxing is "prevent writing to anything outside this dir but still allow reading to most things so that I don't have to manually copy things into a container/VM"
That's what Codex does out of the box, and it's not good against malware - i.e. a rogue npm packet (or even just codex after prompt injection) can read your ssh key and send it to the attacker.
today at 4:29 PM
> That's what Codex does out of the box
As I said, opaque rules built into the harness rub me the the wrong way. They could change in an update without anything making it clear. Plus, I don't use Codex outside of work (I don't have any active paid subscriptions LLM offerings).
> it's not good against malware - i.e. a rogue npm packet (or even just codex after prompt injection) can read your ssh key and send it to the attacker
Ignoring the repeated references to software I don't personally use, I never said I was trying to hedge against malware. The use case for me is when I'm running agents directly based off of prompts that I give them and asking them to modify some files. If I wanted a solution for running code I didn't trust, I wouldn't rely on what I wrote, because that's not the intended use case at all.
today at 3:57 PM
Small world, weāre all working on the same thing!
I went with Docker because history has taught me that new isolation strategies _will_ have escape bugs at some point, and Iām distrustful that the LLM canāt find one if it wants to.
> Probably the biggest (and least hardened) feature that I spent time on in mine was trying to figure out how to allow arbitrary GUI apps so that I could run agents in it via Zed.
I actually have code for this if you want to use/fork/borrow it. TLDR, mine pretends to be an ACP agent so you run Zed on the host, but under the hood that binary is just creating a Docker container with your image and agent, copying files, etc, and then proxying ACP messages via web socket back and forth. Except for the built-in ACP read/write file and shell endpoints. Those get executed inside the container by the proxy by default, though thereās a config option to pass either or both through to the host.
Repo is https://github.com/SethCurry/abyss and the code youād want would be in āinternal/websockets/wsacpā.
It does wrap them in protobuf and thereās some router-like stuff so you can add your own non-ACP messages between the two ends of the proxy.
main also has experimental wasm plugin support in the proxies so you can block prompts/tool calls/whatever in an agent-independent way, or add RAG that works for every agent in the world, or whatever.
today at 3:42 PM
Thank you for building it! I started using Drop a few weeks ago, and I've been very happy with it so far (thanks again for quickly fixing a few issues I've reported :)!).
For me, it nails the convenience vs isolation aspect quite well, and I would like to get to a point where I can use it for all my development by default.
The main challenges that I still have, which none of the solutions I've found so far resolve, are:
- development of containerized applications, where e.g., docker/podman compose is used to bring up services
- development of GUI applications with hardware acceleration, like games (maybe security contexts for pipewire and wayland, like what's done in flatpak would be a good path?)
When I did my research in this space last time, https://litterbox.work/ was another option I've considered, and it is very nice too, but the friction is a bit higher than drop: it's slower to rebuild envs, lacks a "base" config, etc. Drop was much easier to adopt for me so far.
today at 5:48 PM
Thanks! I have GUI applications sandboxing on the roadmap. I also ponder the idea to add VM as the third runtime option (in addition to currently supported native Linux namespaces and gVisor). I'm not yet sure if this is feasible, but VM could allow to start containerized apps within the sandbox as it dodges the nested namespaces problems with containers.
today at 5:38 PM
As everyone mention, there are a lot of implementations of this idea, and not only for agent workflows.
My own approach has the following features, hopefully that gets stolen into an actual softawre package at some point:
- Generate bwrap options (for use in bwrap or gVisor) rather than build the sandbox itself. I wont't trust a random sandbox.
- UDS based automatic HTTP proxy with popup or allowlist and reverse proxy to serve apps. (I won't trust any more net access).
- File based configuration (executable with shebang).
- Composable profiles and command line options for ad-hoc sandboxes.
- Manage system directories (use host's, use another distro's, use an OCI image, etc.) as well as home directory for the sandbox and how the "work" directory is shared.
Drop appears to do a few similar things, and it seems to fit well with how I use such systems. I would like to see more details about how the sandboxes are executed and about the security model.
today at 2:35 PM
Gratulacje Jan! Looks like something critical to gain adoption these days, security-wise. For others who also wonder how it works, I find this docs page a bit more informative than the landing page https://droprun.sh/docs/sandbox-overview/
today at 7:23 PM
I've built something similar, but used landlock instead: https://github.com/denysvitali/boxy
today at 4:32 PM
Can you explain a bit more about the boundary between the environment and my system? Is it just giving read-only access to /usr/lib?
I use an alias to launch a Podman container with opencode in $PWD. It is fully ephemeral aside from the directories I map to it (usually a couple configs). XDG_HOME is local to that working dir. My only frustration is that my image is too minimal but that can be resolved.
today at 5:13 PM
This table shows which dirs are exposed from your system: https://droprun.sh/docs/sandbox-overview/#filesystem-layout
Compared to your setup:
* /usr is from your host, so you don't need to maintain a separate image to have programs that you already have installed.
* username, hostname, your current directory and home dir paths are preserved in the sandbox (within a Podman container a home dir is /root)
* environment variables are easy to carry into the sandbox.
* environments are explicit (`drop ls` lists them) and can be removed with `drop rm`, so you don't need to track in which dirs you have started Podman if you want to cleanup XDG_HOME files.
It is likely that your Podman wrapper also solves some of these or they are non-issues for your. If your setup works well, I wouldn't switch to something different.
today at 5:09 PM
This section of the docs might be helpful for you https://droprun.sh/docs/sandbox-overview/#filesystem-layout
today at 4:54 PM
Glad to see this coming with gVisor support to help secure the Kernel- IMHO we should expect frontier models to find Kernel exploits.
I am working on a project similar in spirit that uses microsandbox (libkrun) to run inside a tiny and fast VM. It includes other security properties that are needed for some workloads.
* network allow lists
* credential masking
* github allow list
https://github.com/gregwebs/agent-vm/#agent-vmtoday at 5:01 PM
Couldn't you use fine grained github tokens for some of what you're accomplishing with the github/network filtering?
today at 7:30 PM
You definitely want to do that. I have a Github App that I use for my AI agents, and that has its own associated restricted credential.
There are going to be cases where you want to white list an org or a repo for read access that is not under your control and Github filtering will be a simple way to do that.
Github can be a source of hostile code, prompt injections, and exfiltration- you may want to lock down using repos that aren't yours.
The tool inherited this feature from the prior implementation and its something I am still exploring.
today at 5:12 PM
The fine-grained tokens have some surprising permissions for "read only" https://github.com/orgs/community/discussions/180063
today at 4:06 PM
So this seems to be useful to me, when you run drop run it starts a child process and places it into a Linux namespace...it gives the process a separate identity and limited privileges so itt can appear to be root inside the sandbox without being root on the host. It also gives it a separate view of the filesystem and all processes inside see their own process tree rather than all host processes. same for network connections.
BUT IT DOESNT WORK ON MAC OS :( bummer (it's Linux-specific)
Guess i'll test it on a VPS
today at 3:17 PM
This is exactly what I was looking for - the website and docs are easy on the brain. I have some apps hosted on distrobox containers that I'd rather not have write access to my home dir.
today at 4:08 PM
Hello, cool project!
Can you explain to me what the benefit of using this is versus something like an LXC container? It is currently my preferred "temp dev env" that behaves like a full system. It can also be customized with cloud-init to load up my preferred settings.
today at 4:10 PM
gVisor virtualizes all syscalls which pass through a host userspace golang process that then maps onto the host's syscalls.
today at 5:28 PM
That sounds like a huge hit to performance
today at 6:15 PM
Per syscall performance overhead has surprisingly low impact on overall performance of programs. gVisor's benchmarks are here: https://gvisor.dev/docs/architecture_guide/performance/
today at 3:40 PM
What do you see as the main advantages of gvisor instead of working within a lightweight VM with full native performance?
As the container escapes with K8s shows, it is super tricky to get isolation right. E.g. what happens if a file you think is safe to write to is suddenly is replaced by one that isnāt.
today at 4:37 PM
My approach with Drop was to start from designing a sandbox user experience. The key idea was to preserve as many aspects of the user's work environment as possible while isolating things that need to be isolated. So keeping the user's distro with all the currently installed packages is the key thing for Drop.
The first Drop version (and the current default runtime) uses Linux namespaces alone to achieve this.
Then, gVisor was added as the second runtime, because it could be done in a way which is completely seamless from the user perspective, both runtimes produce identically looking sandboxes.
A lightweight VM could potentially be a third runtime, but I'm not yet sure it is possible to use a VM in such a way, that the sandbox is configured identically to the first two runtimes. Basically, quickly boot a kernel using the distro already in / and mount the same dirs Drop mounts with two other runtimes. An obvious problem I can already see is that /etc is not fully readable to the user running Drop, so using it to boot a VM will require working around lack of config file access.
Anyway, if VM support was possible, it would obviously have advantage of being fully compatible standard Linux kernel while providing very good isolation of the host kernel. gVisor does have some compatibility issue, as it is re-implementation of the kernel in Go.
Another advantage would be that with VM runtime it would be possible to start containers from Drop, which currently, due to issues related to nested namespaces, is not supported.
today at 4:48 PM
> As the container escapes with K8s shows, it is super tricky to get isolation right. E.g. what happens if a file you think is safe to write to is suddenly is replaced by one that isnāt.
I agree. One thing I'm doing is to review past security problems in popular sandbox and container related projects and check if they apply to Drop. Drop is also rootless only (it won't even start as root), which helps to cut some classes of problems.
today at 7:01 PM
There are a lot of options in this space, but I feel utterly helpless. Which of these are really secure such that I could intentionally run malware without fear of my ssh keys being stolen?
All of the options I find seem to say something along the lines of, āWeāre totally secure so long as you donāt Fizz the Bar or Twiddle the Quanzipulatorā.
What is the most bullet proof, idiot proof option I should use?
today at 2:44 PM
Have you ever tried to use proot?
It does not use process namespaces, and can run on Android (on Termux with proot-distro).
today at 6:03 PM
No, I haven't tried it, thanks for the pointer. It looks like something that could be used by Drop instead of Linux namespaces. I didn't yet encounter any obvious limitation of the namespaces (other that some distros, like Ubuntu, are keeping programs' access to the user namespace creation behind AppArmor allowlist, which makes the Drop installation more involved).
today at 3:19 PM
Why they instead of a microVM?
today at 6:18 PM
[dead]
today at 4:28 PM
I like to use firecracmer, since it has no support for many things, eg host filesystem mounting in the guest.
Can you make any similar guarantees about Drop?
today at 5:58 PM
I mean, Drop does mount host filesystem in the guest, the idea is that you keep working within your current distro and have access to some of its files.
today at 3:44 PM
I've been using gVisor with Docker (or Docker-compatible runtimes) via runsc for years.
It isn't obvious to me what this does that we haven't been able to do for some time now.
today at 3:55 PM
I've been able to use cgroups and net namespaces for years.
It's isn't obvious to me what Docker does that we haven't been able to do for some time now.
today at 5:42 PM
To be honest, me also. I don't even use Docker either but it helps in conversations to keep it simple.
Since it isn't obvious to your, Docker and friends also have an entire content management system (pulling, pushing, tagging images and layers) as well as a build system.
today at 3:19 PM
How is this different than bwrap or srt and others? Im using bwrap to achieve read only everywhere and and write on pwd. Also pi and other coding agents all have sandboxing that work in similar way
today at 4:01 PM
read-only everywhere and write only to the current directory is good if you want to prevent accidental damage, such as a coding agent could make if it hallucinated an invalid command, like `rm -rf ~`.
If you want to prevent a damage from a malicious dependency or a prompt injection, you need more robust protection (for example read-only everywhere exposes your ssh keys). You can build this on top of bwrap, but because it is a low level sandbox building block, you would likely end up creating some higher level abstraction on top of bwrap (for example srt and Flatpak are build on top of bwrap).
Drop is an attempt to create such a generic, high level sandboxing tool. I personally prefer to run agents already within a sandbox than to rely on a coding agent runtime to sandbox itself. Especially that by doing so, I can use the same sandboxing tool and config for installing other programs that need isolation, not just for running agents.
today at 2:38 PM
So, the primary advantage of this over bubblewrap is the insulation layer between the program and kernel syscalls?
today at 2:52 PM
Bubblewrap is a low level tool, it describes itself as a sandbox building block, rather than a high-level sandbox intended to be used directly (for example, Flatpak uses bubblewrap as its building block). Drop in contrast is high-level, designed to be used directly in day-to-day work without the need to assemble the low-level details of the sandbox.
today at 3:22 PM
Does it work within containers?
today at 5:59 PM
Unfortunately not, and it also does not support starting containers from the sandbox.
today at 4:31 PM
[dead]