Getting started
Install
On this page
Use Homebrew on macOS. Use install.sh on Linux, or on a Mac without Homebrew.
| Method | What it installs |
|---|---|
| Homebrew on macOS | brig, brigd, hull, and the shell completions |
install.sh on macOS |
brig, brigd, hull with vz-runner and hvi, and cosign |
install.sh on Linux |
the runtime bundle (nerdctl, containerd, the urunc shim), brig and brigd from the Brig release, and cosign |
| Source build | brig and brigd only, never a runtime |
macOS with Homebrew #
You need a Mac with Apple silicon, macOS 15 or newer, and Homebrew (brew.sh).
brew tap brig-sh/brig
brew trust brig-sh/brig
brew install --cask brigHomebrew puts the binaries on PATH and installs the bash, zsh and fish completions.
brew trust is required. The cask comes from a third-party tap, and Homebrew refuses to install a cask from a tap that is not trusted.
| What you see | What to do |
|---|---|
Unknown command: trust |
Run brew update, then run the command again. |
brew install gives an older version than you expected |
The tap can lag the newest release. Use install.sh. |
brew install fails |
Use install.sh. |
If the host runs macOS 14, read Platform support before you run an agent.
Unreleased builds #
Two extra casks carry builds that are not releases. Use them to try a feature before it reaches a release.
brew install --cask brig-sh/brig/brig@main # the tip of main
brew install --cask brig-sh/brig/brig@experimental # a branch someone promoted| Cask | When it moves | Runtime it pulls |
|---|---|---|
brig@main |
On every merge to main, so brew upgrade follows what is coming |
hull@main |
brig@experimental |
When a maintainer promotes a particular ref to it | hull@experimental |
To get an unmerged branch onto brig@experimental, ask on the pull request, or run the channel workflow with that ref.
Warning Neither cask is supported. They can break, and they move without notice. Do not file a bug report against one, unless the bug is the reason you were asked to install it.
Only one of the three casks can be installed at a time. To go back to the supported build, remove the channel's hull as well:
brew uninstall --cask brig@main hull@main
brew install --cask brigIf you remove only brig@main, hull@main stays. The stable brig then asks for hull, which conflicts with it.
install.sh #
You need curl, tar, and either sha256sum or shasum on PATH.
curl -fsSL https://raw.githubusercontent.com/brig-sh/brig/main/install.sh | shThe script downloads the newest release for your OS and architecture. It checks every archive against a SHA-256 checksum. It installs to BRIG_INSTALL_DIR. If that directory is not writable, it uses sudo.
hull ships as one archive that holds three executables. All three go into the same directory, because hull looks for a runner next to its executable.
| Executable | What it is |
|---|---|
hull |
the CLI Brig drives |
vz-runner |
the Virtualization.framework backend |
hvi |
the Hypervisor.framework backend |
See Linux for what the script installs and where the files go.
The script stops in two cases:
| Host | Result |
|---|---|
Neither sha256sum nor shasum on PATH |
The install stops. It does not skip the checksum. |
| Intel Mac | The install is refused before anything is written. hull runs on Apple silicon only, so there is no runtime to drive. |
install.sh does not install shell completions. See Completions to add them.
install.sh checks each archive by hash. It does not check the cosign signature on checksums.txt. To check the signature, see Release verification.
Settings #
BRIG_INSTALL_DIR=~/bin BRIG_VERSION=v0.2.0 sh install.sh| Variable | Effect |
|---|---|
BRIG_INSTALL_DIR |
Overrides the destination. Unset, the destination is /usr/local/bin. |
BRIG_VERSION |
Pins a Brig release instead of fetching the newest one. |
HULL_VERSION |
Pins a hull release. Brig and hull are versioned independently. |
BRIG_INSTALL_HULL=0 |
Skips hull, and leaves macOS without a runtime. |
BRIG_INSTALL_COSIGN=0 |
Skips cosign, and leaves the boot chain unverified. |
BRIG_INSTALL_ROOTLESS=1 |
Linux only. Asks for the rootless bundle from a node-wide install. See Rootless installs. |
BRIG_INSTALL_RUNTIME=0 |
Linux only. Skips the runtime bundle. See Existing runtime. |
Put BRIG_INSTALL_DIR on your PATH, because hull finds cosign there. If the destination is not on PATH, the boot check reports "no tooling" and install.sh warns you.
cosign #
cosign checks the kernel, initrd and guest agent that every sandbox boots. It also checks the container image behind an agent. If a cosign is already on PATH, install.sh does not install another.
Without cosign on PATH, those checks report "no tooling". In the default mode, Brig prints a warning and still fetches, writes and boots the assets. On a host without Homebrew, HULL_VERIFY=require and BRIG_VERIFY=require are usable only after you install cosign.
cosign is a 130 MB download, the largest item that install.sh installs. install.sh pins it by version and by hash, because the cosign release cannot be checked without cosign.
The macOS build of cosign is ad-hoc signed upstream, and Gatekeeper rejects such a binary. It runs because a curl download carries no quarantine attribute.
Linux #
Brig drives nerdctl over containerd. The urunc shim boots the container as a microVM, so a Linux sandbox does not share the host kernel. The boundary is not identical to the one on macOS: see Security.
install.sh installs all of it from the runtime bundle that brig-standalone-linux publishes. The bundle packages nerdctl, a private containerd and urunc with the monitors and the guest kernel. install.sh pins the bundle tag. The bundle's install.sh is a release asset, checked against the same signed checksums.txt as the bundle.
The bundle also carries a brig and a brigd. install.sh replaces them with the ones from the Brig release, so BRIG_VERSION chooses the Brig version on Linux too. The runtime and Brig are versioned separately.
The bundle puts its launcher on PATH. The launcher sets the environment that points brig at the private containerd.
With the bundle, install.sh ignores BRIG_INSTALL_DIR and reports this, because the binaries go into the bundle's tree.
Install modes #
A node-wide install is the default.
| Node-wide | Per-user | |
|---|---|---|
How to run install.sh |
Under sudo. It needs root. |
As a normal user. It asks for sudo at no point. |
| Tree | /var/lib/brig |
~/.local/share/brig |
| Launcher | /usr/local/bin/brig |
~/.local/bin |
| containerd | The bundle's private containerd | Your own containerd, under a systemd user unit |
| Bundle | The plain bundle, or the rootless one with BRIG_INSTALL_ROOTLESS=1 |
Always the rootless one |
cosign |
Installed by install.sh |
The one the bundle carries |
A per-user install writes nothing outside your home.
A host can have both installs. The node-wide launcher then runs whenever /usr/local/bin comes first on PATH. To run the per-user install, put ~/.local/bin ahead of it:
export PATH="$HOME/.local/bin:$PATH"After it installs the launcher, install.sh checks the order. If another brig comes first, it prints this line.
Rootless installs #
There are two rootless routes:
- A per-user install always takes the rootless bundle. The plain bundle cannot serve it. It reports this and does not install a part of itself.
BRIG_INSTALL_ROOTLESS=1asks for the same bundle from a node-wide install. Each user can then runbrig-ctl rootlessagainst the shared tree.
For either route, a user with root must prepare the host once:
- a subuid range
- access to
/dev/kvmand/dev/vhost-vsock - the
uidmappackage - an AppArmor profile, on Ubuntu 24.04 and later
Before it unpacks anything, the installer reports which of those are missing. The bundle's docs/rootless.md says what each one is for.
oras #
oras fetches the boot bundle for a genericBoot profile. The boot bundle is the kernel and container-initrd that let an ordinary container image boot as a guest.
| Profiles | Need oras |
|---|---|
claude-code, codex, gemini, grok, opencode, ubuntu |
Yes |
claude-desktop, cursor |
No |
Without oras on PATH, a genericBoot run fails. The error names the artifact to fetch by hand and the directory to put it in.
claude-desktop cannot run on Linux. See Platform support.
Existing runtime #
BRIG_INSTALL_RUNTIME=0 skips the bundle and installs brig and brigd alone. Use it on a host that already has nerdctl, containerd and urunc.
That urunc must be a build of the branch that the bundle uses. No urunc release reads the boot annotations, so a genericBoot profile never becomes ready on one. A genericBoot profile also needs oras and cloud-hypervisor, which the bundle carries.
Runtimes covers the full command surface each runtime needs.
docker and runc
docker. docker is accepted in place of nerdctl for an image that carries its own kernel. A genericBoot profile is refused on docker, because docker does not pass the boot annotations urunc needs through to the runtime. Six of the eight shipped profiles are genericBoot.
runc. BRIG_CONTAINERD_RUNTIME=runc asks for a plain container, using runc directly:
BRIG_CONTAINERD_RUNTIME=runc brig run claudeA runc sandbox shares the host kernel with the agent. That is a weaker boundary than a microVM. brig info reports which one a run got.
Source build #
You need Go 1.25.0 or newer, the minimum that go.mod states.
git clone https://github.com/brig-sh/brig
cd brig
make buildmake build writes brig and brigd into the current directory. It does not build a runtime.
A source build of Brig needs no signing and no entitlement, because Brig reaches the hypervisor only through hull.
A hull built from source cannot boot a sandbox without a Developer ID certificate. See Runtimes for what that needs.
Verify the install #
brig version
brig doctorbrig version prints the version you installed. brig doctor prints one line per check: host, virtual, runtime, boot, verify, profiles, secrets, brigd and image. Each line carries one of three marks: ok, !! or --.
| Line | Meaning |
|---|---|
ok beside runtime |
Brig found the hull or nerdctl it drives, and where. |
!! beside boot |
Normal before you run an agent. Brig fetches boot assets on first use. |
!! anywhere else |
The line names the fix beside it. |
Next: Quickstart.
Release verification #
This step is optional. You need cosign. You also need checksums.txt, checksums.txt.pem and checksums.txt.sig, downloaded with the archive from the release page.
cosign verify-blob \
--certificate checksums.txt.pem \
--signature checksums.txt.sig \
--certificate-identity-regexp \
'^https://github\.com/brig-sh/brig/\.github/workflows/release\.yml@refs/tags/v' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
checksums.txt
shasum -a 256 -c checksums.txt --ignore-missingThe first command checks the signature on checksums.txt with keyless cosign. There is no key. A short-lived certificate, bound to the identity of the release workflow, takes its place.
The second command checks the archives against the hashes in checksums.txt.
The macOS binaries also carry a Developer ID signature, notarized with Apple. Gatekeeper checks that signature, and does not check the cosign one.
spctl -a -vv -t install "$(which brig)" # source=Notarized Developer IDSecurity says what each check proves, and why Brig signs releases this way.
Platform support #
| Host | Supported |
|---|---|
| Mac, Apple silicon, macOS 15 or newer | Yes |
| Mac, Apple silicon, macOS 14 | Yes, with BRIG_HYPERVISOR=vz BRIG_NETWORK=shared |
| Intel Mac | No |
| Linux, x86-64 or arm64 | Yes, with the runtime bundle install.sh installs |
macOS 15 is the minimum that Brig enforces for hull's hvi backend. The project tests on macOS 26. Neither Brig nor hull refuses macOS 15 or macOS 16 because it is older than 26.
claude-desktop limits #
claude-desktop is a graphical profile, and it has three limits:
| Limit | Reason |
|---|---|
| It cannot run on Linux. | The Linux runtime refuses a graphical profile, on nerdctl and on docker alike. The refusal names macOS as where it can run. |
| On macOS it needs Apple silicon. | Its image is published for arm64 only. |
It needs the vz backend. |
vz is the only one of the three backends with a console. A graphical profile is refused on hvi and qemu. |
brig agent ls lists claude-desktop on every platform, with no marker of these limits.
macOS 14 and Intel Macs
macOS 14. Set both variables before you run an agent:
export BRIG_HYPERVISOR=vz
export BRIG_NETWORK=sharedSix of the eight shipped profiles ask for hvi. hvi depends on an in-kernel interrupt controller that Apple first shipped in macOS 15. On an older macOS, Brig refuses the run before the virtual machine monitor can crash. BRIG_HYPERVISOR=vz avoids that minimum.
Those profiles also ask for isolated networking, which vz cannot provide. BRIG_NETWORK=shared covers that for every run. You can pass --network shared on each run instead. The shared network does not promise to separate sandboxes. See Policies for the network postures.
The refusal needs a version that Brig can read from the host. If the host does not report its version, Brig does not refuse the run and proceeds to the boot.
Intel Macs. Brig's source does not check the host architecture. The release publishes a darwin/amd64 archive of brig and brigd with the arm64 one. A manual download or a source build of brig succeeds on an Intel Mac. A run then fails at the runtime check, because Brig finds no hull to drive. hull needs Apple silicon, and no amd64 build of hull exists.