{ description = "Sandboxed MicroVMs"; # nixConfig = { # extra-substituters = [ "https://microvm.cachix.org" ]; # extra-trusted-public-keys = [ "microvm.cachix.org-1:oXnBc6hRE3eX5rSYdRyMYXnfzcCxC7yKPTbZXALsqys=" ]; # }; inputs = { nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable"; microvm = { url = "github:microvm-nix/microvm.nix"; inputs.nixpkgs.follows = "nixpkgs"; }; # nullclaw.url = "github:illustris/nullclaw?ref=sqlite-on-9p"; nullclaw.url = "path:///home/illustris/src/nullclaw"; nix-mcp.url = "github:illustris/nix-mcp"; }; outputs = { self, nixpkgs, microvm, nullclaw, nix-mcp }: let system = "x86_64-linux"; macFromName = name: let hash = builtins.hashString "sha256" name; b = i: builtins.substring (i * 2) 2 hash; in "02:${b 0}:${b 1}:${b 2}:${b 3}:${b 4}"; mkMicrovm = name: { vcpu ? 2, mem ? 2048, extraModules ? [] }: nixpkgs.lib.nixosSystem { inherit system; modules = [ microvm.nixosModules.microvm ({ pkgs, ... }: { networking.hostName = name; users.users.root.password = ""; services.getty.autologinUser = "root"; microvm = { hypervisor = "qemu"; inherit vcpu mem; socket = "${name}.socket"; interfaces = [{ type = "user"; id = "usernet"; mac = macFromName name; }]; shares = [ { proto = "9p"; tag = "ro-store"; source = "/nix/store"; mountPoint = "/nix/.ro-store"; } { proto = "9p"; tag = "${name}-data"; source = "/home/illustris/Documents/microvms/data/${name}"; mountPoint = "/var/lib/${name}"; } ]; # qemu.extraArgs = [ # "-fw_cfg" "name=opt/claude-auth,file=/home/illustris/.claude.json" # ]; }; nix = { nixPath = [ "nixpkgs=${pkgs.path}" ]; settings.experimental-features = [ "nix-command" "flakes" ]; }; system.stateVersion = "25.11"; }) ] ++ extraModules; }; in { packages.${system} = nixpkgs.lib.mapAttrs (_: v: v.config.microvm.declaredRunner) self.nixosConfigurations; nixosModules.storeOverlay = { microvm.writableStoreOverlay = "/nix/.rw-store"; fileSystems."/nix/.rw-store" = { fsType = "tmpfs"; options = [ "size=4G" "mode=0755" ]; neededForBoot = true; }; }; nixosConfigurations = nixpkgs.lib.mapAttrs mkMicrovm { cc-sandbox = { vcpu = 8; mem = 8192; extraModules = [({ pkgs, ... }: { nixpkgs.config.allowUnfree = true; nix = { registry.nix-mcp = { from = { type = "github"; owner = "illustris"; repo = "nix-mcp"; }; to = nix-mcp; }; settings.experimental-features = [ "nix-command" "flakes" ]; }; services.openssh.enable = true; users.users.root.openssh.authorizedKeys.keys = [ "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAm3qVkTmuYEayM3Vstruv8w5SM4K9riokAxUcpothhO illustris@illustris-thinkpad" ]; environment.systemPackages = with pkgs; [ claude-code-bin git curl vim nix-mcp.packages.x86_64-linux.default tmux ]; microvm = { writableStoreOverlay = "/nix/.rw-store"; forwardPorts = [ { from = "host"; host.port = 2222; guest.port = 22; } ]; shares = [ { proto = "9p"; tag = "claude-config"; source = "/home/illustris/.claude"; mountPoint = "/var/lib/claude-lower"; readOnly = true; } ]; qemu.extraArgs = [ "-fw_cfg" "name=opt/claude-auth,file=/home/illustris/.claude.json" ]; }; systemd.services.claude-auth = { description = "Copy Claude auth token from fw_cfg"; wantedBy = [ "multi-user.target" ]; before = [ "multi-user.target" ]; serviceConfig = { Type = "oneshot"; ExecStart = "/bin/sh -c 'cp /sys/firmware/qemu_fw_cfg/by_name/opt/claude-auth/raw /root/.claude.json && chmod 600 /root/.claude.json'"; RemainAfterExit = true; }; }; fileSystems = { # tmpfs backing for the writable nix store overlay "/nix/.rw-store" = { fsType = "tmpfs"; options = [ "size=4G" "mode=0755" ]; neededForBoot = true; }; # Claude config: ephemeral overlay on top of host's ~/.claude "/var/lib/claude-rw" = { fsType = "tmpfs"; options = [ "size=128M" "mode=0700" ]; }; "/root/.claude".overlay = { lowerdir = [ "/var/lib/claude-lower" ]; upperdir = "/var/lib/claude-rw/upper"; workdir = "/var/lib/claude-rw/work"; }; }; })]; }; nullclaw = { vcpu = 2; mem = 4096; extraModules = [({ pkgs, ... }: { imports = [ self.nixosModules.storeOverlay ]; fileSystems = { "/root" = { device = "/var/lib/nullclaw"; options = [ "bind" ]; }; "/root/.cache/nix" = { fsType = "tmpfs"; options = [ "size=1G" "mode=0700" ]; }; }; environment.systemPackages = with pkgs; [ nullclaw.packages.${system}.default tmux git strace bpftrace ]; })]; }; vpn = { vcpu = 2; mem = 2047; extraModules = [({ pkgs, ... }: { imports = [ self.nixosModules.storeOverlay ]; # Mount ovpn configs read-only microvm.shares = [ { proto = "9p"; tag = "ovpn"; source = "/home/illustris/Documents/ovpn/air"; mountPoint = "/etc/openvpn/air"; readOnly = true; } ]; # OpenVPN client service services.openvpn.servers.airvpn = { config = '' config /etc/openvpn/air/AirVPN_United-States_UDP-443.ovpn ''; autoStart = true; }; environment.systemPackages = with pkgs; [ openvpn rclone tmux nmap ]; })]; }; crash = {}; }; }; }