Quick start
This walks through confining a program you do not trust, from nothing to a working policy.
1. Look before you run
Every run resolves a policy first. Ask what it will be:
bailey show ./programprofile base: untrusted
config layers: (none)
filesystem:
r-x /bin
r-- /etc
r-x /lib
r-x /lib64
r-- /proc
r-x /sbin
r-- /sys
r-x /usr
network:
egress: DenyAll
bind_ports: []
devices:
rw- /dev/full
rw- /dev/null
r-- /dev/random
rw- /dev/tty
r-- /dev/urandom
rw- /dev/zero
resources: ResourceLimits { memory_bytes: None, pids_max: None, cpu_percent: None }That is the untrusted floor profile: enough for a dynamically linked binary to start, and nothing else. No home directory, no network, no GPU.
2. Run it
bailey run ./programThe program itself is granted implicitly, as the lowest layer, so a binary outside the system paths starts without any config. Everything else it wants is denied, which is usually the next thing you find out.
3. Add what it actually needs
Put a bailey.toml next to the program and add grants one at a time:
[filesystem]
read = ["."]
write = ["./data"]Paths are relative to the config file's own directory, so . here means the directory the program lives in.
When you cannot guess, stop guessing and record a session:
bailey audit --save-trace trace.json ./programThe output lists every access the current policy does not grant, with the high-risk ones separated out. Turn the reviewed trace into a profile:
bailey profile generate --trace trace.json --target ./program > bailey.tomlSee auditing a program for the whole loop.
4. Turn on isolation
By default, ungranted paths are denied but still visible: the program can see that /home/you/.ssh exists, it just cannot open it. Isolation rebuilds the world so those paths are not there at all, and host processes are invisible:
bailey run ./programThis needs unprivileged user namespaces. Where they are unavailable, bailey warns and falls back to Landlock and seccomp.
Isolation also gives the program a private /tmp, a private home, and the directory you invoked it from, so relative paths work as they do outside. See environment and storage.
5. Start from a profile
Rather than building a policy from nothing, start from one shaped for your case:
bailey profile list
bailey run --profile native-game ./gameProfiles are additive over the untrusted floor, and your own config layers on top of them. See profiles.
Where to go next
- Configuration for the full config model.
- The policy model for how layers resolve.
- Known limitations for what is not enforced yet. Read this one before you rely on the sandbox for anything that matters.