fitting closely and comfortably · marked by cordiality and secure privacy · offering safe concealment · a small private room in a pub
A lightweight, opinionated sandbox for Linux, well integrated with the host.
Main properties are
- Rootless, daemonless: No
suidhelpers, no root at any point. - Declarative: TOML profiles, which can be combined together.
--dry-runshows every grant. - Modern Linux tools:
bwrap,pasta, namespaces, seccomp, dropped capabilities. - Protects the host: no
~/.ssh/,~/.gnupgor~/.kube/inside. Host parts are hidden by default. - Safe host integration: proxies for
ssh-agent,gpg-agentand the Kubernetes API, filtered configuration forclaude. - Podman engine: safe podman engine enabling docker-style dev workflows.
- Network off by default:
@netadds egress throughpasta. Host loopback stays unreachable. - HTTP doors: host can open a door into sandbox using systemd socket activation protocol.
- Small supply chain: Go without cgo, two dependencies (a TOML parser,
golang.org/x/sys).
Project state The internal architecture, the profile model, CLI options and a configuration are expected to be well defined and stable. However it still MAY change. Use at your own discretion.
LLM generated code Majority of the code has been generated by LLM agents. Feel free to not use the tool in case you don't like the way it was written. AI agents (redteam, policy, sandbox-tester) regularly try to escape the sandbox closing the doors once they're discovered.
There is a spectrum of tools to choose from. There's a global non-isolated shell on one side, shell scripts calling bwrap, dev containers and full virtual machines.
snug itself is a bwrap sandbox with bells and whistles like pasta
support for networking, proxies for ssh and gpg and support for a fully
isolated podman engine.
That means it
- shares the kernel
- shares the storage
- can share the egress network
- expects all tools installed
So use snug if
- You're fine with sharing the same kernel. Otherwise use a virtual machine, Firecracker, gVisor or similar.
- You're fine with it not installing anything. Use a dev container otherwise.
- You're happy with your tooling. Keep using it.
snug must be built with CGO_ENABLED=0, so the easiest way is to type make build.
# build the binary
$ make build
# inspect if the system can run snug - reports missing dependencies
$ ./bin/snug doctor
# fix subuids - I am sure most Linux users have no idea
# what this is and what to write there - use -w in case you're OK with snug writing to /etc
$ ./bin/snug fix subuid$ cd ~/src/myproject
$ echo "hello from host" > hello
# Entering a sandbox
$ snug ~/src/myproject
# ~/.ssh and the like are not accessible by default
🔒 snug:~/src/myproject$ ls ~/.ssh
ls: cannot access '/home/you/.ssh': No such file or directory
# The parent is hidden, because it was not granted by any profile.
🔒 snug:~/src/myproject$ ls ..
myproject
# succeeds, but it's stored in a tmpfs and lost on exit
🔒 snug:~/src/myproject$ echo "hello" > ../hello
# the target directory is read-write because of @target-rw
🔒 snug:~/src/myproject$ cat hello
hello from host
🔒 snug:~/src/myproject$ echo "hello from snug" > hello
🔒 snug:~/src/myproject$ cat hello
hello from snug
# Network is not available
🔒 snug:~/src/myproject$ curl https://example.com
curl: (6) Could not resolve host: example.com
🔒 snug:~/src/myproject$ exit
# @net adds egress
$ snug -p @net ~/src/myproject
🔒 snug:~/src/myproject$ curl -s -o /dev/null -w '%{http_code}\n' https://example.com
200Unlike the code, the user guide is reviewed by me, so any mistakes are my own oversight.
.claude/design/ is design material for Claude.
- Linux with unprivileged user namespaces
bubblewrapgetentfrom glibc or musl-utilspastaand/dev/net/tunfor@net- a delegated subuid/subgid range and
newuidmap/newgidmapfor@netand containers podmanwithcrun,conmon,netavark,aardvark-dnsandcatatonitfor@podman-*- Go 1.26+ to build
snug doctor checks all of these and tells how to fix them.
MIT