Sandboxing
When you bake a process recipe, Brioche needs to run a command on your machine. But, Brioche aims to make builds as reliable as possible, and software is very messy and can do different things depending on what other software is installed on your machine or how your machine is set up! To try and make baking process recipes as reliable as possible, we run the process’s command in a sandbox. In other words, we aim for builds to be hermetic. This doesn’t guarantee that the command will always work across different machines, but it helps to prevent some cases where a build can work on one machine but fail on another. “Works on your machine?” Well, it should work on mine, too!
Warning: Process sandboxing is not intended as a security feature! Do not run malicious programs within the sandbox. Malicious software within the sandbox could infect the host machine!
Sandboxing works differently depending on the host platform, but there are some things a process can rely on when run:
$HOME
is set to a writable directory$TMPDIR
is set to a writable directory- The working directory starts in an empty directory within
$HOME
. This directory can be populated with contents by setting theworkDir
option when constructing the process recipe. $BRIOCHE_OUTPUT
is set to a path that the process must write to before exiting (otherwise, baking the process will fail). Initially, this path does not exist, but this path can be populated by setting theoutputScaffold
option when constructing the process recipe (after which, the process can then modify the contents of this path).$BRIOCHE_RESOURCE_DIR
is set to a writable directory. This is a special directory used for packed executables.$BRIOCHE_INPUT_RESOURCE_DIRS
is set to a colon-separated (:
) list of readable directories. These directories are used for packed executables.- The
command
,args
, andenv
options can take process templates (std.tpl
). When these templates include a recipe, it will expand to an absolute path of the baked recipe’s contents. You should assume these paths are read-only.
Unsafe processes
Because builds are meant to be hermetic, Brioche will by default restrict processes from doing certain things out of the box that could break hermeticity, such as network access. In some cases, processes can opt in to some of these unsafe feature explicitly.
Rules for unsafe
There aren’t strict rules for whether the use of unsafe in Brioche is valid or invalid— it’s really dependent on context. But, in general, you should stay away from using unsafe to pull in resources that might change over time (where those changes could make your build valid or invalid). Builds are still cached based only on their inputs, so if a remote URL changes out from under you, for example, it’s your responsibility to make sure both the old content and the new content are still valid inputs for your build!
- Valid: Using unsafe to clone a Git repo to check out a specific commit
- Invalid: Using unsafe to download the
main
branch of a repo to try and keep in sync with the latest source code - Valid: Using unsafe to pull in Node.js dependencies based on a lockfile
- Invalid: Using unsafe to pull in Node.js dependencies without a lockfile and not isolating yourself from breaking changes from dependencies
Unsafe options
You can enable unsafe by setting unsafe: true
or by calling .unsafe({ /* ... */ })
on a process recipe. Here are the available unsafe options:
networking
: Enable direct network access through the host machine
Platform details
Even with sandboxing, what the system looks like to a sandboxed process will look pretty different depending on which platform it runs on.
Linux
On Linux, processes are sandboxed using Linux namespaces by default to isolate or control different parts of the environment when the process runs. For more details, see the section on configuring the linux_namespace
backend.
On Linux, the sandbox will include executables at /bin/sh
and /usr/bin/env
. However, it’s best practice not to rely on these paths where possible! This is because there are no guarantees about what features are exactly offered by these binaries, or even which program is used for implementing them under the hood. For example, /bin/sh
could eventually be changed to Bash, Dash, Zsh, Busybox’s shell, or some other shell. For consistency, it’s better to use a specific shell explicitly.
Sandbox backends
Brioche supports multiple different configurations for sandboxing processes, and it’ll always try to pick the best method for sandboxing processes on your machine by default.
In some cases, you may still want to manually change or experiment with different sandboxing settings, or you may need to customize the sandbox if Brioche can’t pick a good default for your machine. The “Sandbox configuration” section describes the different backends, and the different options for each.