Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions documentation/docs/guides/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,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.
Expand Down
172 changes: 106 additions & 66 deletions documentation/docs/guides/sandbox.md
Original file line number Diff line number Diff line change
@@ -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.
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).

## What Gets Restricted
## Configuration

### File System (seatbelt)
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.

By default, the sandbox blocks writes to:
### Core

| 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 |
| Variable | Default | Description |
|----------|---------|-------------|
| `GOOSE_SANDBOX` | `false` | Set to `true` or `1` to enable the sandbox. See [Quick Start](#quick-start) for launch instructions. |

### Network (seatbelt)
----

All direct network access is denied. The only allowed paths are:
### File System

- **Localhost** — so the process can reach the egress proxy and its own server port
- **Unix sockets** — for local IPC
- **mDNSResponder** — for DNS resolution
The [seatbelt sandbox profile](https://github.com/block/goose/blob/main/ui/desktop/src/sandbox/index.ts) blocks write operations to these sensitive files:

Everything else must go through the proxy.
- `~/.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

### 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
#### Environment Variables

### Network (proxy)
| Variable | Default | Description |
|----------|---------|-------------|
| `GOOSE_SANDBOX_PROTECT_FILES` | `true` | Write-protect sensitive files listed above. Set to `false` to disable |

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
### Direct Network Access

## Configuration
The seatbelt sandbox denies all direct network access, forcing traffic through the proxy. The only allowed connections are:

All configuration is via environment variables. Defaults are designed to be secure out of the box.
- **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

### Core
:::info Not Configurable
These restrictions are always active when the sandbox is enabled.
:::

| Variable | Default | Description |
|----------|---------|-------------|
| `GOOSE_SANDBOX` | `false` | Set to `true` or `1` to enable the sandbox |
----

### Process Restrictions

The seatbelt sandbox blocks tools and system calls that could bypass security controls:

### Seatbelt Profile
- **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 |
|----------|---------|-------------|
Expand All @@ -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.

Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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.
5 changes: 5 additions & 0 deletions documentation/docs/guides/security/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down
Loading