What is sandboxing, and what does it entail?

There are two manual entries:

They complement and contradict each other at the same time, and below is how I interpret “sandboxing” when trying to consolidate the two.

I’m all for making the Nixpkgs manual entry short using @kamadorueda’s concise summary

Sandbox allows you to build derivations in an empty file system, without access to the internet, and on a perfectly empty environment, so pretty much it ensures the build step is a pure function without side effects or visibility to the outside world


Overview

When sandbox builds are enabled, Nix will set up an isolated environment for each build process by constraining build inputs1 to improve reproducibility.

It is achieved by isolating build jobs from input sources whose contents are prone to change dynamically and without notice. For example, the main2 file system hierarchy is completely bypassed to prevent depending on files in global directories, such as /usr/bin, where a reference to an executable may point to different version as time goes by.

WARNING: The use of a sandbox requires that Nix is run as root (so you should use the “build users” feature to perform the actual builds under different users than root).

Allowed input sources for sandboxed builds

Files can only be referenced from

  • [Linux, macOS, *BSD]7 the Nix store
  • [Linux, macOS, *BSD]7 the temporary build directory3
  • [Linux, macOS, *BSD]7 the paths configured with the sandbox-paths option.
  • [Linux, macOS, *BSD]7 fixed-output derivations (i.e., the results of fetch* commands)
  • [Linux]7 “private versions” of
    • /proc
    • /dev
    • /dev/shm
    • /dev/pts

The last item is only available on Linux, and “private version” refers to the fact that builds run in

  1. separate PIDs, and
  2. mount, network, IPC, and UTS namespaces distinct from the main system one4

NOTE: Fixed-output derivations do not run in a private network namespace to ensure they can access the network.

Accepted values

NOTE: The default is true on Linux and false on all other platforms.5

Usage

  • Globally enable on NixOS by adding the nix.useSandbox option to your configuration.nix.

    For example:

    nix.useSandbox = true;
    
  • Globally enable sandboxing on non-NixOS platforms by add the following to your nix.conf:

    sandbox = true
    
  • Ad hoc usage via nix* commands’ --option 6

Supported platforms


[1]: Chose the term “build input” instead of “dependency” because it seems that the source also falls in this category, and I usually see “dependency” used as to mean the building blocks needed to realize the blueprint that is the source, hence they are not the same category in my mind. Could be totally wrong though.

[2]: Used “main” instead of “normal” but it may even be omitted entirely because it doesn’t seem to add any value, and “file system hierarchy” already means (at least to me) “the files and directories present on one’s system (i.e., laptop, desktop, VM, container, etc.)”

[3]: Does this refer to $out?

[4]: Does this sound ok? I know nothing about Linux namespaces.

[5]: In contrast, the Nixpkgs manual section 19.5.1. Tested using sandboxing says that

Sandboxing is not enabled by default in Nix due to a small performance hit on each build.

So which one is it?

[6]: Didn’t look into the specifics, and this is coming directly from a reply:

Sandbox is an option ( --option ) you can pass to nix-build and other commands, it exists on:

  • Nix 2.3 (stable)
  • Nix 2.4 (unstable)
  • Nix 2.4 (unstable) with Flakes support (a.k.a. passing --experimental-features flakes ) (Sometimes they call this Nix 3.0)

[7]: To what extent are BSDs supported? I honestly don’t know. According to what I’ve found, Nix is supported on FreeBSD and also on NetBSD (see also this HN comment), so I presume that “sandboxing” works, barring Linux-specific features.

I believe most of these other links refer to “supporting non-Linux kernels in NixOS” (which means that NixOS as a concept would be welded on top of Windows, Unix, etc.?)

5 Likes

I think the temporary build directory is the place where the derivation is actually built. You can keep the temporary build directory of failed builds by enabling keep-failed setting. By default they are located under /tmp and named like nix-build-<pname>-<version>.drv-<index>

$out refers to the Nix store path of the output named “out” of the derivation. By default derivations have a single output named “out”, so $out can be thought of as the same thing as the derivation itself. Derivation outputs like $out are usually created/populated during installPhase.


Sandboxing is enabled by default on NixOS. Since NixOS is also a Linux distribution, saying it is enabled by default on Linux would be wrong otherwise.

I think it is not enabled by default in Nix while it is enabled by default on NixOS and Linux in general.


nix has --sandbox, --no-sandbox and other flags related to sandboxing. [1]


  1. nix - Nix Reference Manual ↩︎

2 Likes

I guess sandbox = true can’t work in docker/podman, right?