Partial rootless overlay store in container?

I’m trying to set up an LLM coding assistant workflow (with opencode) that’s adequately sandboxed in a container, but also has access to the dev shell flake that has all of the tools my project needs for building (and nothing else).

The requirements:

  1. The container has access to the already-built packages in the host nix store for the dev shell tools. I’ve already built them, and rebuilding/downloading them in each container seems wasteful.
  2. The container can’t edit the host nix store, because I don’t trust my LLM tools that much.
  3. The container can’t see anything in the nix store that’s not required for the dev shell flake. Because I build other projects with nix, and I don’t want to expose all that to the LLM.
  4. Rootless. Whatever script I’m going to call to set all this up won’t have root access, because that same script will start the container and LLM tool, and I don’t even want to accidentally give that stuff root access.

I have not yet found a workflow to allow this, but I’ve found some pieces that look promising:

For giving the container access to the nix store, there’s the experimental local-overlay-store option. This looks like it grant access to the full store, but it’s definitely a step in the right direction.

One catch to that option though, is that it requires an overlay filesystem mount to be made separately, which appears to require root access. Separately, I have found that podman supports overlay volume mounts, which don’t appear to require root access, and may be enough for the local overlay store to work. (aside: what’s up with the overlay mount syntax on this page? Is that a different version, or ai hallucination?)

I have no solid leads on exposing only part of the store, but given that the dev shell is a flake, I can, in principle, identify all the packages the flake requires, but then do I bind each one separately? I’m led to believe neither symlinks nor hardlinks would make this easier.

This whole thing strikes me as a really common use case for LLM tooling on nix-related projects, so I’m hoping someone else has just taken care of all of this.

Current leading backup plan: just build the dev shell package in the local directory, and include that in the project workspace bind mount.

2 Likes

I hacked something vaguely similar up for Opencode using Bubblewrap . Maybe it’ll be applicable to you.

That looks really close to what I want. I’d have to change a few things for my use case (don’t want to give it access to every directory in a monorepo, and don’t want to give it edit control of its own config), but that’s small stuff.

Am I reading it right that the subset of the store its exposing is based on static package lists? If so, autodetecting a dev shell in the project directory doesn’t seem like a big step either.

A kind of similar thing I’ve tracked down is jail.nix, but this seems better for me.

Yes, it’s statically determining the subset of the nix store to expose. It feels like handling dev shells should work. Let me know if you figure it out.

I haven’t looked at performance with a bunch of binds, and some of the microvm alternatives I’ve seen are more secure. I mainly wanted something small and understandable to mitigate non-malicious risks.