Nixwrap is a command line utility to easily wrap processes in a sandbox preventing them from accessing your system. Nixwrap can hinder access to environment variables, files, devices and the network. Under the hood, Nixwrap is based on Bubblewrap which in turn uses Linux Namespaces.
The goal of Nixwrap is to make sandboxing easy to use for common use cases, reducing the barrier to entry. While it will not provide perfect protection against any untrusted code, it does add protection for simple common threads.
You need to run
npm install
on a project, but you cannot trust all its dependencies.
To run npm install
only with write access to the current working directory and network access, simply do:
wrap -n npm install
You need to run a GUI application, but you want limit access to your filesystem.
To run software using nix3-run
, in this case vscodium with network and display access, without access to your home directory:
wrap -n -d -p nix run nixpkgs#vscodium
You need to run a
python
script that has access to your audio hardware.
Run a python script with Pulse Audio and Pipewire access, but not sharing the current working directory:
wrap -a -p python my-tool.py
By default, Nixwrap will:
- ✅ Prevent network access. (Use
-n
to allow.) - ✅ Prevent access to Wayland and X. (Use
-d
(desktop) to allow.) - ✅ Prevent camera access. (Use
-c
to allow.) - ✅ Prevent audio access. (Use
-a
to allow.) - ✅ Prevent DBus socket access. (Use
-b
to allow.) - ✅ Prevent access to user name information. (Use
-u
to allow.) - ❗ Allow write access to the current working directory.
- ❗ Allow read only access to all paths in
$NIX_PROFILES
. - ❗ Allow read only access to nix store and config and bin paths.
- ❗ Allow access to a set of common environment variables.
wrap [OPTIONS] -- [bwrap args] [program to wrap with args]
-w PATH Mount PATH into sandbox in read write mode.
-r PATH Mount PATH into sandbox in read-only mode.
-d Allow Wayland display and rendering hardware access.
-b Allow DBus access.
-n Allow Network access.
-a Allow Audio access.
-c Allow Camera access.
-u Allow System user information access.
-e VAR Allow env var VAR access.
-v Verbose output for debugging.
-p Do not share current working directory. By default wrap will share
the current working directory as a write mount and cd into it
before running the program. With this option, wrap will not share
the directory and leave the current directory untouched.
-m Manual unsharing. By default wrap unshares ipc, net, pid, and uts
and tries to unshare (continue on failues) user and cgroup
namespaces. With this option, wrap does not automatically unshare
any namespaces. Use together with bwrap --unshare-* options
(man bwrap(1)) to unshare manually.
Add the Nixwrap flake as an input in your flake.
{
inputs = {
wrap.url = "github:rti/nixwrap";
};
# outputs ...
}
To wrap a package, use the function from inputs.wrap.lib.wrap
. It takes the following arguments:
package
The package to wrap.executable
The name of the executable, optional, defaults to package name.wrapArgs
Arguments to wrap, see above.
The function returns a new package wrapping the given package.
E.g. to wrap nodejs
with access to current working directory (default) and additional network access, do:
inputs.wrap.packages.wrap {
package = pkgs.nodejs;
executable = "node";
wrapArgs = "-n";
}
This example installs nodejs
in a devShell, but wraps node
with Nixwrap, so what it can only access the current working directory and the network.
{
inputs.nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
inputs.wrap.url = "github:rti/nixwrap";
outputs = { nixpkgs, wrap, ... } @inputs:
inputs.flake-utils.lib.eachDefaultSystem (
system:
let
pkgs = nixpkgs.legacyPackages.${system};
in
{
devShells.default = pkgs.mkShell {
buildInputs = [
(wrap.lib.${system}.wrap {
package = pkgs.nodejs;
executable = "node";
wrapArgs = "-n";
})
];
};
}
);
}
Nixwrap is at the moment tested exclusively on NixOS, even though the concept should work in any distribution that ships a current kernel.
wrap
is licensed under the MIT License. See the LICENSE file for more details.