Profiles are composable sandbox configs. Stack them: sx online rust -- cargo build
Always included (unless inherit_base = false). Provides:
- Read access to system directories (
/usr,/bin,/sbin,/Library,/System) - Read access to shell configs (
~/.zshrc,~/.bashrc…) - Write access to
/tmpand session temp dir - Basic env vars (
TERM,PATH,HOME,USER,SHELL)
Always denied (even if you allow ~):
~/.ssh~/.aws~/.docker/config.json~/Documents,~/Desktop,~/Downloads
Full network access.
sx online -- curl https://example.com127.0.0.1 only. For dev servers.
sx localhost -- npm startRust/Cargo toolchain:
- Read/write:
~/.cargo,~/.rustup - Env:
CARGO_HOME,RUSTUP_HOME
sx rust online -- cargo buildBun runtime:
- Read/write:
~/.bun - Parent directory listing for module resolution (
/Users,~) - Env:
BUN_INSTALL,NODE_ENV
sx bun online -- bun installClaude Code:
- Read/write:
~/.claude,~/.claude.json - Includes
onlinenetwork - Env:
ANTHROPIC_API_KEY
sx claude -- claude --dangerously-skip-permissions --continueGPG signing:
- Read/write:
~/.gnupg
sx gpg -- git commit -S -m "signed"Order matters for network mode (last wins). Filesystem paths merge.
# Rust with network
sx rust online -- cargo build
# Rust offline (tests with cached deps)
sx rust -- cargo test
# Claude with GPG signing
sx claude gpg -- claude --dangerously-skip-permissions
# Bun with network
sx bun online -- bun installCreate in ~/.config/sx/profiles/:
# ~/.config/sx/profiles/mycompany.toml
network_mode = "online"
allow_exec_sugid = ["/bin/ps"] # allow specific setuid/setgid binaries
[filesystem]
allow_read = ["/opt/mycompany"]
allow_write = ["~/.mycompany/cache"]
[shell]
pass_env = ["MYCOMPANY_TOKEN"]Use it:
sx mycompany -- ./run.shFor advanced use cases (IOKit, Mach services, app bundles), custom profiles support raw seatbelt rules:
# ~/.config/sx/profiles/playwright.toml
network_mode = "online"
[seatbelt]
raw = """
(allow iokit-open-user-client
(iokit-user-client-class "RootDomainUserClient")
(iokit-user-client-class "AGXDeviceUserClient")
(iokit-user-client-class "IOSurfaceRootUserClient"))
(allow iokit-get-properties)
(allow file-issue-extension)
"""
[filesystem]
allow_read = ["~/Library/Caches/ms-playwright/"]
allow_write = ["~/Library/Caches/ms-playwright/"]Raw rules are appended verbatim to the generated seatbelt profile. Use sx --dry-run myprofile to verify the output.
When you specify a profile name, sx searches in this order:
- Built-in profiles (embedded in the binary)
- Project custom directory (if configured)
~/.config/sx/profiles/{name}.toml- Fallback to
onlinewith a warning if not found
In .sandbox.toml:
[sandbox]
profiles = ["rust", "localhost"]- Network mode: last profile with a mode wins
- Filesystem paths: union (no duplicates)
- Env vars: union of pass/deny lists
- Exec sugid: path lists are unioned; mixing paths and booleans → last wins
- Seatbelt raw rules: concatenated from all profiles in order