Skip to content

mirql/devenv-sandbox

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

devenv-sandbox

A devenv module that runs profile-driven bubblewrap sandboxes as devenv scripts. Enable it, declare a profile, and get a sandbox-<name> command that drops you into an isolated shell with a persistent home, deny-by-default network, and only the mounts and secrets you allow.

Requires Linux (bubblewrap + unprivileged user namespaces).

Use it in your project

devenv.yaml:

inputs:
  sandbox:
    url: github:mirql/devenv-sandbox   # this repo
    flake: false
imports:
  - sandbox

devenv.nix:

{ ... }: {
  sandbox.enable = true;
  sandbox.profiles.dev = {
    blocks = [ "ssh" "git" ];                 # reusable building blocks
    network.enable = false;                   # deny-by-default
    mounts.rw.project.src = "~/code/myproject";
    env.set.EDITOR = "nvim";
  };
}

Then:

devenv shell sandbox-dev                      # enter the sandbox
devenv shell sandbox-dev -- zsh -c 'id; echo $SANDBOX'
SANDBOX_DRYRUN=1 devenv shell sandbox-dev     # print the bwrap command, run nothing

Pin to a commit for reproducibility (url: github:mirql/devenv-sandbox/<commit>) and bump with devenv update.

Use it from a Nix flake

If your project drives devenv from a flake.nix, add this repo as an input and pass the exported module to devenv.lib.mkShell:

{
  inputs = {
    nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling";
    devenv.url = "github:cachix/devenv";
    sandbox.url = "github:mirql/devenv-sandbox";   # this repo (a flake)
  };

  outputs = { nixpkgs, devenv, sandbox, ... } @ inputs:
    let system = "x86_64-linux"; in {
      devShells.${system}.default = devenv.lib.mkShell {
        inherit inputs;
        pkgs = nixpkgs.legacyPackages.${system};
        modules = [
          sandbox.devenvModule
          { sandbox.enable = true; sandbox.profiles.dev.blocks = [ "ssh" "git" ]; }
        ];
      };
    };
}

Enter with nix develop --no-pure-eval, then run sandbox-dev.

Blocks

Block Adds
ssh read-only ~/.ssh
git read-only ~/.gitconfig
nvim read-write ~/.config/nvim + ~/.local/share/nvim
ai-keys passthrough OPENAI_API_KEY, ANTHROPIC_API_KEY, GITHUB_TOKEN

Profile options

  • blocks — list of block names from the table above
  • network.enable — share the host network (default: off)
  • mounts.ro.<name> / mounts.rw.<name>{ src, dst ? null }
  • env.passthrough — host env var names to forward if set
  • env.set — env vars to set inside the sandbox
  • roBinds — system paths bound read-only (sensible defaults)

See examples/ai-dev/ for a full profile composing all four blocks. That example imports the module via a local ../.. path; a real consumer imports it by input name as shown above.

Layout

devenv.nix              module entrypoint (imports ./modules/sandbox.nix)
flake.nix               exposes the module for flake-based consumers
modules/
  sandbox.nix           options + config (generates one script per profile)
  launcher.sh           the runtime shim (home seeding, mounts, exec bwrap)
examples/ai-dev/        a consumer using blocks = [ ... ]

About

Profile-driven bubblewrap sandboxes as a devenv module

Topics

Resources

License

Stars

1 star

Watchers

0 watching

Forks

Packages

 
 
 

Contributors