sx uses macOS Seatbelt (sandbox-exec) to isolate processes. Deny-by-default.
Supply chain attacks. That one compromised npm package in your dependency tree running a postinstall script, trying to exfiltrate ~/.aws or plant malware.
sx protects against:
- Credential theft - Can't read
~/.ssh,~/.aws,~/.docker/config.json - Data exfiltration - Filesystem is deny-by-default, network is offline by default
- Malware drops - Write access limited to working directory and
/tmp
Everything blocked unless explicitly allowed:
(version 1)
(deny default)| Category | Access |
|---|---|
| Working directory | Read/write |
System binaries (/usr, /bin) |
Read-only |
Temp (/tmp) |
Read/write |
| Everything else | Denied |
Always denied (even if you allow ~):
| Path | What |
|---|---|
~/.ssh |
SSH keys |
~/.aws |
AWS credentials |
~/.docker/config.json |
Docker credentials |
~/Documents, ~/Desktop, ~/Downloads |
Personal files |
Everything else (~/.config/gh, ~/.netrc, ~/.gnupg…) is blocked by deny-by-default. Use profiles like gpg to allow specific paths.
| Mode | Effect |
|---|---|
offline (default) |
All blocked |
localhost |
127.0.0.1 only |
online |
Full access |
Even with online, your credentials can't be read. Can't exfiltrate what you can't see.
Blocked by default:
AWS_**_SECRET**_PASSWORD**_KEY
(version 1)
(deny default)
; Process operations
(allow process-fork)
(allow process-exec)
(allow signal (target self))
; Required for path resolution
(allow file-read* (literal "/"))
(allow file-read-metadata) ; Required for DNS resolution
; Working directory
(allow file* (subpath "/path/to/project"))
; Denied paths (override allows)
(deny file-read* (subpath "/Users/me/.ssh"))
(deny file-read* (subpath "/Users/me/.aws"))
; System paths
(allow file-read* (subpath "/usr"))
(allow file-read* (subpath "/bin"))
; Network (based on mode)
; offline: nothing
; localhost: (allow network-outbound (to ip "localhost:*"))
; online: (allow network*)- Root bypass - Root can escape any sandbox
- Kernel bugs - Sandbox depends on kernel security
- Side channels - Timing attacks not prevented
- Existing processes - Only affects new processes
- Default to
offlineunless network required - Use
localhostfor dev servers - Review custom profiles before trusting them
- Use
--traceto debug denials