docs: update sandbox topic (#7336)

This commit is contained in:
dianed-square
2026-02-19 12:11:55 -08:00
committed by GitHub
parent ddd35f6d47
commit 6e9be07491
3 changed files with 128 additions and 75 deletions
@@ -460,6 +460,14 @@ When the keyring is disabled (or cannot be accessed and goose [falls back to fil
* Windows: `%APPDATA%\Block\goose\config\secrets.yaml`
:::
### macOS Sandbox for goose Desktop
Optional [macOS sandbox](/docs/guides/sandbox) for goose Desktop that restricts file access, network connections, and process execution using Apple's `sandbox-exec` technology.
| Variable | Purpose | Values | Default |
|----------|---------|--------|---------|
| `GOOSE_SANDBOX` | Enable the sandbox with [customizable security controls](/docs/guides/sandbox#configuration) | `true` or `1` to enable | `false` |
## Network Configuration
These variables configure network proxy settings for goose.
+115 -75
View File
@@ -1,83 +1,116 @@
# macOS Sandbox for goosed
---
title: macOS Sandbox for goose Desktop
sidebar_label: Sandbox for goose Desktop
description: Optional sandboxing for goose Desktop to control file access, filter network traffic, and enforce security policies on macOS
---
goose includes an optional macOS sandbox that restricts the goosed process using Apple's seatbelt (`sandbox-exec`) and routes all network traffic through a local egress proxy. This limits what the agent can do on your system — blocking sensitive file writes, raw sockets, tunneling tools, and unapproved network destinations.
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:
> **Requirements:** macOS only. The sandbox relies on `/usr/bin/sandbox-exec` which is only available on macOS.
- **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-exec` restricts file and network access at the system level
- **Outbound connections** - A local egress proxy filters and logs outgoing connections
:::info macOS Requirement
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
Set the environment variable before launching the goose desktop app:
To enable the sandbox, launch goose Desktop from the terminal with the environment variable set. For example:
```bash
GOOSE_SANDBOX=true
export GOOSE_SANDBOX=true
open -a Goose
```
Then start the desktop app as normal. goose will:
When the app starts with sandboxing enabled, it will:
1. Generate a seatbelt sandbox profile
2. Start a local HTTP CONNECT proxy on localhost
3. Launch goosed inside `sandbox-exec`, forcing all traffic through the proxy
3. Launch the `goosed` backend for goose Desktop inside `sandbox-exec`, forcing all traffic through the proxy
If `sandbox-exec` is not available (e.g. you're on Linux), goose will fail fast with a clear error rather than running unsandboxed.
## What Gets Restricted
### File System (seatbelt)
By default, the sandbox blocks writes to:
| Path | Purpose |
|------|---------|
| `~/.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 |
### Network (seatbelt)
All direct network access is denied. The only allowed paths are:
- **Localhost** — so the process can reach the egress proxy and its own server port
- **Unix sockets** — for local IPC
- **mDNSResponder** — for DNS resolution
Everything else must go through the proxy.
### Process Restrictions (seatbelt)
- **Tunneling tools blocked:** `nc`, `ncat`, `netcat`, `socat`, `telnet` — prevents the agent from bypassing the proxy
- **Raw sockets blocked:** `SOCK_RAW` on `AF_INET`/`AF_INET6` — prevents raw packet crafting
- **Kernel extensions blocked:** `system-kext-load` denied
### Network (proxy)
The egress proxy checks connections in this order:
1. **Loopback detection** — prevents using the proxy as a relay back to localhost
2. **Raw IP blocking** — connections to bare IP addresses (no domain) are blocked
3. **Domain blocklist** — domains listed in `blocked.txt` are denied (including all subdomains)
4. **SSH/Git host restrictions** — SSH ports (22, 2222, 7999) are restricted to known git hosts
5. **LaunchDarkly allowlist** (optional) — dynamic egress control via feature flag
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.
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 |
| `GOOSE_SANDBOX` | `false` | Set to `true` or `1` to enable the sandbox. See [Quick Start](#quick-start) for launch instructions. |
### Seatbelt Profile
----
### File System
The [seatbelt sandbox profile](https://github.com/block/goose/blob/main/ui/desktop/src/sandbox/index.ts) 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 `goosed` process to reach the egress proxy and its own server port
- **Unix sockets** — For local inter-process communication (IPC)
- **mDNSResponder** — For DNS resolution
:::info Not Configurable
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`, `telnet` are blocked to prevent bypassing the proxy
- **Raw sockets** — `SOCK_RAW` on `AF_INET`/`AF_INET6` is blocked to prevent raw packet crafting
- **Kernel extensions** — `system-kext-load` is denied
#### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `GOOSE_SANDBOX_PROTECT_FILES` | `true` | Write-protect `~/.ssh` and shell configs. Set to `false` to disable |
| `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 |
### Proxy
----
### 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:
1. **Loopback detection** — Prevents using the proxy as a relay back to localhost
2. **Raw IP blocking** — Connections to bare IP addresses (no domain) are blocked
3. **Domain blocklist** — Domains listed in `blocked.txt` are denied (including all subdomains)
4. **SSH/Git host restrictions** — SSH ports (22, 2222, 7999) are restricted to known git hosts
For optional LaunchDarkly-based egress control, see [LaunchDarkly](#launchdarkly-optional).
#### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
@@ -87,16 +120,7 @@ All configuration is via environment variables. Defaults are designed to be secu
| `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) |
### LaunchDarkly (optional — not required)
LaunchDarkly is **not required**. The sandbox works fully without it using the local `blocked.txt` blocklist. These settings only apply if your organization uses LaunchDarkly for dynamic egress control.
| 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` |
## Domain Blocklist
#### 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.
@@ -109,13 +133,15 @@ transfer.sh
webhook.site
```
**Live reload:** Changes to `blocked.txt` take effect immediately — the proxy watches the file with `fs.watch` and reloads it automatically. No restart needed.
:::tip Live Reload
Changes to `blocked.txt` take effect immediately — the proxy watches the file with `fs.watch` and reloads it automatically. No restart needed.
:::
## SSH and Git
#### Using Git Over SSH
SSH git operations (`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.
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 (GitHub, GitLab, Bitbucket, etc.). To customise:
By default, SSH is only allowed to well-known git hosting domains (e.g. GitHub, GitLab, Bitbucket). To customize:
```bash
# Add custom git hosts
@@ -125,6 +151,19 @@ export GOOSE_SANDBOX_GIT_HOSTS="github.com,gitlab.com,your-gitea.internal.com"
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
@@ -148,7 +187,7 @@ export GOOSE_SANDBOX=true
export GOOSE_SANDBOX_ALLOW_SSH=false
```
### Relaxed mode (sandbox on, fewer restrictions)
### Relaxed mode (fewer restrictions)
```bash
export GOOSE_SANDBOX=true
@@ -169,14 +208,15 @@ export GOOSE_SANDBOX_LD_FAILOVER=blocklist # fall back to local blocklist if LD
## Troubleshooting
**"GOOSE_SANDBOX=true but sandbox-exec is not available (macOS only)"**
You're not on macOS, or `/usr/bin/sandbox-exec` is missing. The sandbox only works on macOS.
- **Error: "GOOSE_SANDBOX=true but sandbox-exec is not available (macOS only)"**
You're not on macOS, or `/usr/bin/sandbox-exec` is 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 enable `GOOSE_SANDBOX_ALLOW_IP=true` for IP-based endpoints.
- **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 enable `GOOSE_SANDBOX_ALLOW_IP=true` for IP-based endpoints.
**Git clone over SSH fails**
The target host may not be in the default git hosts allowlist. Add it with `GOOSE_SANDBOX_GIT_HOSTS=your-host.com` or set `GOOSE_SANDBOX_SSH_ALL_HOSTS=true`.
- **git clone over SSH fails**
The target host may not be in the default Git hosts allowlist. Add it with `GOOSE_SANDBOX_GIT_HOSTS=your-host.com` or set `GOOSE_SANDBOX_SSH_ALL_HOSTS=true`.
- **Want to inspect what the proxy is blocking?**
Check the [Desktop application logs](/docs/guides/logs#desktop-application-log). Blocked connections are logged with the prefix `[sandbox-proxy]` and include the reason for blocking.
**Want to inspect what the proxy is blocking?**
Check the Electron/goosed logs — blocked connections are logged with the reason.
@@ -25,6 +25,11 @@ import styles from '@site/src/components/Card/styles.module.css';
description="API specification for self-hosting ML-based prompt injection detection endpoints."
link="/docs/guides/security/classification-api-spec"
/>
<Card
title="macOS Sandbox for goose Desktop"
description="Control file access, network connections, and process restrictions for goose Desktop using Apple's sandbox technology."
link="/docs/guides/sandbox"
/>
</div>
</div>