macOS Sandbox for goose Desktop
goose Desktop includes an optional macOS sandbox that you can enable when you need stricter control and visibility over what goose can access on your system. Use it to:
- Restrict file system access — Block writes to SSH keys, shell configs, and goose configuration files
- Control network connections — Force all traffic through a filtering proxy that blocks unapproved domains
- Prevent security bypasses — Block tunneling tools, raw sockets, and other techniques that could circumvent restrictions
- Audit and enforce policies — Log all network activity and enforce compliance requirements
goose runs with full tool access, but the sandbox uses two layers of protection:
- File access control - Apple's
sandbox-execrestricts file and network access at the system level - Outbound connections - A local egress proxy filters and logs outgoing connections
The sandbox relies on /usr/bin/sandbox-exec, which is only available on macOS and is also known as Apple's seatbelt technology.
Quick Start
To enable the sandbox, launch goose Desktop from the terminal with the environment variable set. For example:
export GOOSE_SANDBOX=true
open -a Goose
When the app starts with sandboxing enabled, it will:
- Generate a seatbelt sandbox profile
- Start a local HTTP CONNECT proxy on localhost
- Launch the
goosedbackend for goose Desktop insidesandbox-exec, forcing all traffic through the proxy
The sandbox remains active until you quit goose Desktop. To disable it, quit the app and relaunch normally (or set GOOSE_SANDBOX=false when opening from the terminal).
Configuration
All configuration is via environment variables. Defaults are designed to be secure out of the box, but you can adjust them to match your security requirements.
Core
| Variable | Default | Description |
|---|---|---|
GOOSE_SANDBOX | false | Set to true or 1 to enable the sandbox. See Quick Start for launch instructions. |
File System
The seatbelt sandbox profile blocks write operations to these sensitive files:
~/.ssh/- Prevent SSH key tampering~/.bashrc,~/.zshrc,~/.bash_profile,~/.zprofile- Prevent shell config injection~/.config/goose/sandbox/- Protect sandbox config from the sandboxed process~/.config/goose/config.yaml- Protect goose config
Environment Variables
| Variable | Default | Description |
|---|---|---|
GOOSE_SANDBOX_PROTECT_FILES | true | Write-protect sensitive files listed above. Set to false to disable |
Direct Network Access
The seatbelt sandbox denies all direct network access, forcing traffic through the proxy. The only allowed connections are:
- Localhost — Allows the
goosedprocess to reach the egress proxy and its own server port - Unix sockets — For local inter-process communication (IPC)
- mDNSResponder — For DNS resolution
These restrictions are always active when the sandbox is enabled.
Process Restrictions
The seatbelt sandbox blocks tools and system calls that could bypass security controls:
- Tunneling tools —
nc,ncat,netcat,socat,telnetare blocked to prevent bypassing the proxy - Raw sockets —
SOCK_RAWonAF_INET/AF_INET6is blocked to prevent raw packet crafting - Kernel extensions —
system-kext-loadis denied
Environment Variables
| Variable | Default | Description |
|---|---|---|
GOOSE_SANDBOX_BLOCK_RAW_SOCKETS | true | Block SOCK_RAW. Set to false to disable |
GOOSE_SANDBOX_BLOCK_TUNNELING | true | Block nc/netcat/socat/telnet. Set to false to disable |
Network Filtering
The egress proxy inspects and filters all outgoing connections. You can customize filtering rules through the blocklist file and configuration variables.
The egress proxy checks connections in this order:
- Loopback detection — Prevents using the proxy as a relay back to localhost
- Raw IP blocking — Connections to bare IP addresses (no domain) are blocked
- Domain blocklist — Domains listed in
blocked.txtare denied (including all subdomains) - SSH/Git host restrictions — SSH ports (22, 2222, 7999) are restricted to known git hosts
For optional LaunchDarkly-based egress control, see LaunchDarkly.
Environment Variables
| Variable | Default | Description |
|---|---|---|
GOOSE_SANDBOX_ALLOW_IP | false | Set to true to allow connections to raw IP addresses |
GOOSE_SANDBOX_BLOCK_LOOPBACK | false | Set to true to block loopback relay through the proxy |
GOOSE_SANDBOX_ALLOW_SSH | true | Set to false to block all SSH traffic |
GOOSE_SANDBOX_GIT_HOSTS | built-in list | Comma-separated list of allowed SSH git hosts (e.g. github.com,gitlab.com) |
GOOSE_SANDBOX_SSH_ALL_HOSTS | false | Set to true to allow SSH to any host (not just git hosts) |
Managing the Domain Blocklist
The file ~/.config/goose/sandbox/blocked.txt controls which domains are blocked by the proxy. It's created automatically on first run from a bundled template.
# One domain per line. Subdomains are blocked automatically.
# Lines starting with # are comments.
evil.com # blocks evil.com and *.evil.com
pastebin.com
transfer.sh
webhook.site
Changes to blocked.txt take effect immediately — the proxy watches the file with fs.watch and reloads it automatically. No restart needed.
Using Git Over SSH
SSH git operations (e.g. git clone git@github.com:...) work through the sandbox via a bundled connect-proxy.pl script that acts as an SSH ProxyCommand. This routes SSH connections through the egress proxy, which then applies the same allowlist rules.
By default, SSH is only allowed to well-known git hosting domains (e.g. GitHub, GitLab, Bitbucket). To customize:
# Add custom git hosts
export GOOSE_SANDBOX_GIT_HOSTS="github.com,gitlab.com,your-gitea.internal.com"
# Or allow SSH to all hosts
export GOOSE_SANDBOX_SSH_ALL_HOSTS=true
LaunchDarkly (Optional)
For enterprise environments, LaunchDarkly provides optional dynamic egress control. If not configured, the sandbox uses the local blocked.txt blocklist.
Environment Variables
| Variable | Default | Description |
|---|---|---|
LAUNCHDARKLY_CLIENT_ID | — | LD client SDK key to enable dynamic egress control |
GOOSE_SANDBOX_LD_FAILOVER | — | Failover mode if LD is unreachable: allow, deny, or blocklist |
Example Configurations
Maximum security
export GOOSE_SANDBOX=true
# All protections enabled (defaults)
Allow raw IP connections (e.g. for internal APIs)
export GOOSE_SANDBOX=true
export GOOSE_SANDBOX_ALLOW_IP=true
Disable SSH entirely
export GOOSE_SANDBOX=true
export GOOSE_SANDBOX_ALLOW_SSH=false
Relaxed mode (fewer restrictions)
export GOOSE_SANDBOX=true
export GOOSE_SANDBOX_PROTECT_FILES=false
export GOOSE_SANDBOX_BLOCK_RAW_SOCKETS=false
export GOOSE_SANDBOX_BLOCK_TUNNELING=false
export GOOSE_SANDBOX_ALLOW_IP=true
export GOOSE_SANDBOX_SSH_ALL_HOSTS=true
With LaunchDarkly egress control
export GOOSE_SANDBOX=true
export LAUNCHDARKLY_CLIENT_ID=sdk-your-key-here
export GOOSE_SANDBOX_LD_FAILOVER=blocklist # fall back to local blocklist if LD is down
Troubleshooting
-
Error: "GOOSE_SANDBOX=true but sandbox-exec is not available (macOS only)"
You're not on macOS, or/usr/bin/sandbox-execis missing. The sandbox only works on macOS. -
Extensions or tools can't reach the network
Check if the destination domain is in~/.config/goose/sandbox/blocked.txt, or if you need to enableGOOSE_SANDBOX_ALLOW_IP=truefor IP-based endpoints. -
git clone over SSH fails
The target host may not be in the default Git hosts allowlist. Add it withGOOSE_SANDBOX_GIT_HOSTS=your-host.comor setGOOSE_SANDBOX_SSH_ALL_HOSTS=true. -
Want to inspect what the proxy is blocking?
Check the Desktop application logs. Blocked connections are logged with the prefix[sandbox-proxy]and include the reason for blocking.