# Sandboxing

## **Sandboxing** ([v6.1.0](https://docs.tabnine.com/main/getting-started/tabnine-cli/features/pages/risy3bTOlfBfgFRRXK8K#v6.1.0))

Sandboxing ([v6.1.0](https://docs.tabnine.com/main/getting-started/tabnine-cli/features/pages/risy3bTOlfBfgFRRXK8K#v6.1.0)) in Tabnine CLI is an OS-level process isolation mechanism that enforces hard filesystem and network boundaries around the CLI process itself. When sandbox mode is active, the CLI runs inside a process jail enforced by the operating system kernel — using macOS Seatbelt (`sandbox-exec`) on macOS, or a container runtime (Docker, Podman, or others) on Linux and Windows. The OS prevents the process from reading or writing outside permitted paths, regardless of what the AI agent attempts.

This is distinct from the tool-approval layer (controlled by `--approval-mode`), which governs which agent actions require your confirmation. See Tool Approval vs. Sandbox Mode for a full comparison.

***

### **How Sandbox Mode Works**

When you enable sandbox mode, Tabnine CLI re-launches itself as a child process inside a sandbox environment. The sandbox backend is selected automatically based on your platform:

1. **macOS** — Uses `sandbox-exec` (Apple Seatbelt), a kernel-enforced SBPL profile. No external tools required.
2. **Linux** — Prefers Docker, then Podman, then `lxc`, then `runsc` (gVisor).
3. **Windows** — Uses a native Windows sandboxing mechanism (`windows-native`).

You can also specify a backend explicitly instead of relying on auto-detection (see Configuration).

#### **Filesystem Isolation**

The sandbox restricts which paths the process can read from and write to. Write access is always limited to a defined allowlist regardless of strictness level. Read access varies by the macOS profile selected (see macOS Sandbox Profiles). On container-based backends, the working directory and `.tabnine` config paths are mounted into the container.

#### **Network Isolation**

Network access is controlled independently of filesystem isolation. Two modes are available:

* **Open** — All outbound network connections are permitted.
* **Proxied** — Only connections through a local proxy (listening on `localhost:8877`) are permitted. Set via `TABNINE_SANDBOX_PROXY_COMMAND`.

***

### **When to Use Sandbox Mode**

Use sandbox mode when you need an enforceable guarantee that the CLI process cannot access or modify files outside your working directory, or cannot make unrestricted network connections. Unlike approval mode, sandbox restrictions are enforced by the OS — the AI agent cannot bypass them even if it tries.

Sandbox mode is a strong fit for:

* Analyzing code from an untrusted or unfamiliar repository
* Running Tabnine CLI in a CI/CD pipeline with restricted system access
* Auditing a project for security issues in a controlled environment
* Ensuring the CLI cannot touch files outside the current project directory
* Working in environments where a security team requires verifiable process isolation

If your goal is to review and approve each agent action interactively (rather than enforce hard OS-level boundaries), `--approval-mode default` is usually a better fit. Sandbox mode is stricter and non-interactive by design.

***

### **Quickstart**

**Enable sandboxing with a command flag**

```shell
tabnine -s -p "analyze the code structure"
```

**Use an environment variable**

*macOS/Linux*

```shell
export TABNINE_SANDBOX=true
tabnine -p "review the architecture"
```

*Windows (PowerShell)*

```
$env:TABNINE_SANDBOX="true"
tabnine -p "review the architecture"
```

**Configure in settings.json**

```json
{
  "tools": {
    "sandbox": true
  }
}
```

***

### **macOS Sandbox Profiles**

On macOS, the sandbox is implemented using Apple Seatbelt (`sandbox-exec`) with one of six built-in SBPL profiles. The profile controls how strictly filesystem access is constrained and whether network access is open or proxied.

Select a profile by setting the `SEATBELT_PROFILE` environment variable before invoking `tabnine`. If unset, the default is `permissive-open`.

| Profile                       | Read Access                                                                        | Write Access    | Network                       |
| ----------------------------- | ---------------------------------------------------------------------------------- | --------------- | ----------------------------- |
| `permissive-open` *(default)* | Everywhere (allow default)                                                         | Allowlist only¹ | All outbound                  |
| `permissive-proxied`          | Everywhere (allow default)                                                         | Allowlist only¹ | Proxied only (localhost:8877) |
| `restrictive-open`            | Explicit allowlist (target dir, system paths, \~/.tabnine, \~/.nvm, \~/.config, …) | Allowlist only¹ | All outbound                  |
| `restrictive-proxied`         | Same as `restrictive`                                                              | Allowlist only¹ | Proxied only (localhost:8877) |
| `strict-open`                 | Narrow allowlist (target dir + essential dotfiles + explicit system paths only)    | Allowlist only¹ | All outbound                  |
| `strict-proxied`              | Same as `strict`                                                                   | Allowlist only¹ | Proxied only (localhost:8877) |

¹ Write allowlist: working directory, system temp dir, `~/.tabnine`, `~/.cache`, `~/.npm`, `~/.gitconfig`, and any paths passed via `--include-directories` (up to 5).

```shell
# Use the most restrictive profile with proxied network
SEATBELT_PROFILE=strict-proxied tabnine -s -p "audit this codebase"
```

***

### **Tool Approval vs. Sandbox Mode**

These are two separate, independently configurable features that address different concerns.

|                             | `--sandbox` / `-s`                               | `--approval-mode`                                |
| --------------------------- | ------------------------------------------------ | ------------------------------------------------ |
| **What it controls**        | OS-level process isolation                       | Which AI agent actions require user confirmation |
| **Enforcement**             | Kernel / container runtime                       | CLI application logic                            |
| **Can the AI bypass it?**   | No                                               | No (but scope is different)                      |
| **Affects file writes?**    | Yes — OS blocks them outside allowlist           | Yes — prompts or auto-approves based on mode     |
| **Affects shell commands?** | Yes — restricted by the OS sandbox profile       | Yes — controlled by approval policy              |
| **Network restrictions?**   | Yes — open or proxied, per profile               | No                                               |
| **Requires external tool?** | On macOS: no. On Linux/Windows: Docker or Podman | No                                               |

**You can use both together.** For example, running with `-s --approval-mode default` gives you OS-level isolation *and* interactive confirmation of every agent action.

#### **Approval Mode Reference**

| Mode                                                                                                                    | Behavior                                                          |
| ----------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `default`                                                                                                               | Prompts for confirmation before every file edit and shell command |
| `auto_edit`                                                                                                             | Auto-approves file edits; prompts for shell commands              |
| `yolo`                                                                                                                  | Auto-approves everything (use with caution)                       |
| `plan` ([v6.1.0](https://docs.tabnine.com/main/getting-started/tabnine-cli/features/pages/risy3bTOlfBfgFRRXK8K#v6.1.0)) | Agent plans actions and presents them; no automatic execution     |

```shell
# OS isolation + interactive confirmation of every action
tabnine -s --approval-mode default -p "your prompt"
```

***

### **Configuration**

#### **Enable Sandboxing (in order of precedence)**

1. **Command-line flag** — Pass `-s` or `--sandbox`.

```shell
tabnine -s -p "your prompt here"
```

2. **Environment variable** — Set `TABNINE_SANDBOX`.

*macOS/Linux*

```shell
export TABNINE_SANDBOX=true
tabnine -p "your prompt here"
```

*Windows (PowerShell)*

```
$env:TABNINE_SANDBOX="true"
tabnine -p "your prompt here"
```

You can also set `TABNINE_SANDBOX` to a specific backend name instead of `true`, which skips auto-detection:

| Value            | Effect                                                                  |
| ---------------- | ----------------------------------------------------------------------- |
| `true` or `1`    | Auto-detect backend (macOS: `sandbox-exec`; Linux: `docker` → `podman`) |
| `sandbox-exec`   | Force macOS Seatbelt (macOS only)                                       |
| `docker`         | Force Docker container backend                                          |
| `podman`         | Force Podman container backend                                          |
| `lxc`            | Force LXC container backend (Linux only)                                |
| `runsc`          | Force gVisor via Docker (Linux only; requires Docker)                   |
| `windows-native` | Force Windows native sandbox (Windows only)                             |

3. **Configuration file** — In `settings.json`, set `"sandbox"` under `"tools"`.

*Settings file location:*

* **macOS/Linux**: `~/.tabnine/agent/settings.json`
* **Windows**: `%USERPROFILE%\.tabnine\agent\settings.json`

**Boolean form** (auto-detect backend):

```json
{
  "tools": {
    "sandbox": true
  }
}
```

**String form** (specify backend explicitly):

```json
{
  "tools": {
    "sandbox": "docker"
  }
}
```

**Object form** (full control):

```json
{
  "tools": {
    "sandbox": {
      "enabled": true,
      "command": "docker",
      "networkAccess": false,
      "allowedPaths": ["/path/to/extra/dir"],
      "image": "your-org/custom-sandbox-image:latest"
    }
  }
}
```

| Field           | Type      | Default         | Description                                               |
| --------------- | --------- | --------------- | --------------------------------------------------------- |
| `enabled`       | boolean   | —               | Whether sandboxing is active                              |
| `command`       | string    | auto-detect     | Backend to use (`docker`, `podman`, `sandbox-exec`, etc.) |
| `networkAccess` | boolean   | `true`          | Set to `false` to block all outbound network              |
| `allowedPaths`  | string\[] | `[]`            | Additional filesystem paths to mount/allow                |
| `image`         | string    | Tabnine default | Custom container image (Docker/Podman only)               |

You can also set `sandboxNetworkAccess` as a top-level tools setting:

```json
{
  "tools": {
    "sandbox": true,
    "sandboxNetworkAccess": false
  }
}
```

#### **Additional Environment Variables**

| Variable                        | Description                                                                                                                                                               |
| ------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SEATBELT_PROFILE`              | macOS only. Selects the Seatbelt profile: `permissive-open` *(default)*, `permissive-proxied`, `restrictive-open`, `restrictive-proxied`, `strict-open`, `strict-proxied` |
| `TABNINE_SANDBOX_IMAGE`         | Override the container image used for Docker/Podman backends                                                                                                              |
| `TABNINE_SANDBOX_PROXY_COMMAND` | Command to launch a proxy for `proxied` network profiles (must listen on `localhost:8877`)                                                                                |

***

### **Verification**

To confirm sandbox mode is active, run with debug output:

```shell
DEBUG=1 tabnine -s -p "your prompt"
```

Look for a log line such as:

```
hopping into sandbox (command: sandbox-exec) ...
```

or, for container backends:

```
hopping into sandbox (command: docker) ...
```

If this line does not appear, sandbox mode is not active.

***

### **Troubleshooting**

#### **Common Issues**

**`FatalSandboxError: TABNINE_SANDBOX is true but failed to determine command for sandbox`**

* No compatible sandbox backend was found on your system.
* On Linux: install Docker or Podman, or set `TABNINE_SANDBOX` to a specific backend name.
* On macOS: `sandbox-exec` is built in and should always be available. If this error appears on macOS, try setting `TABNINE_SANDBOX=sandbox-exec` explicitly.

**`FatalSandboxError: Invalid sandbox command '...'`**

* The value of `TABNINE_SANDBOX` is not a recognized backend name.
* Valid values: `docker`, `podman`, `sandbox-exec`, `lxc`, `runsc`, `windows-native`.

**`FatalSandboxError: Missing sandbox command '...'`**

* The specified backend binary is not installed or not on `PATH`.
* Install the required tool (e.g., `brew install docker`) or choose a different backend.

**`FatalSandboxError: gVisor (runsc) sandboxing is only supported on Linux`**

* `runsc` is Linux-only. Use `docker` or `podman` on macOS/Windows instead.

**`FatalSandboxError: Missing macos seatbelt profile file '...'`**

* The value of `SEATBELT_PROFILE` does not match any of the six built-in profiles.
* Valid values: `permissive-open`, `permissive-proxied`, `restrictive-open`, `restrictive-proxied`, `strict-open`, `strict-proxied`.

**Agent cannot write files or run commands (expected)**

* This is correct behavior. The OS sandbox restricts writes to the defined allowlist.
* If writes to a specific directory are required, pass it via `--include-directories` or add it to `allowedPaths` in `settings.json`.

**`Sandbox image '...' is missing or could not be pulled`**

* Docker/Podman cannot pull the sandbox container image.
* Check your network connection, or set `TABNINE_SANDBOX_IMAGE` to an image already present locally.

***

### **Alternatives to Sandbox Mode**

If you need safety without OS-level process isolation, the approval mode system provides interactive guardrails without requiring Docker or a container runtime.

#### **Approval Modes**

**Default mode** — prompt before every file edit and shell command:

```shell
tabnine --approval-mode default
```

**Auto-edit mode** — auto-approve file edits, prompt for shell commands:

```shell
tabnine --approval-mode auto_edit
```

**Plan mode** — agent plans and presents actions; no automatic execution:

```shell
tabnine --approval-mode plan
```

#### **Persist a Default Approval Mode**

```json
{
  "general": {
    "defaultApprovalMode": "default"
  }
}
```

#### **Disable Session Retention for Sensitive Work**

```json
{
  "general": {
    "sessionRetention": {
      "enabled": false
    }
  }
}
```

***

### **Security Best Practices**

1. **Use sandbox mode for untrusted code review** — Always enable sandbox when analyzing code from unknown sources. OS-level isolation provides a verifiable boundary that approval mode alone does not.
2. **Prefer stricter macOS profiles for sensitive environments** — Use `SEATBELT_PROFILE=strict-proxied` when you want both narrow filesystem read access and restricted network egress.
3. **Combine sandbox with `--approval-mode default`** — For modifiable sessions, pairing OS isolation with interactive confirmation gives you two independent layers of control.
4. **Limit workspace scope with `--include-directories`** — Restrict the AI's context to specific folders. These paths are also the only additional write targets allowed by the macOS sandbox profiles.
5. **Use `networkAccess: false` or a proxied profile for air-gapped review** — Set `"networkAccess": false` in `settings.json` or use a `*-proxied` Seatbelt profile to prevent the sandboxed process from making outbound connections.
6. **Never combine `--yolo` with `--sandbox` on untrusted code** — YOLO mode auto-approves all agent actions. Even inside a sandbox, this removes the interactive safeguard layer. Use `--approval-mode default` instead.
7. **Review `settings.json` regularly** — Check `~/.tabnine/agent/settings.json` for persistent sandbox settings that may carry over between sessions.

***

### **Frequently Asked Questions**

**Q: Can the AI access the internet in sandbox mode?**

A: It depends on the configuration. Container-based backends (Docker, Podman) allow network access by default unless `"networkAccess": false` is set. On macOS, the `*-open` Seatbelt profiles allow all outbound connections, while `*-proxied` profiles restrict network to a local proxy on `localhost:8877`. To enforce no network access, set `"networkAccess": false` in `settings.json` or use `SEATBELT_PROFILE=strict-proxied` with `TABNINE_SANDBOX_PROXY_COMMAND` unset.

**Q: Does sandbox mode make the AI read-only?**

A: Not exactly. Sandbox mode enforces OS-level filesystem boundaries — the process cannot write outside the defined allowlist. However, the AI agent's tools (such as `write_file` and `replace`) remain available; the OS sandbox will cause those operations to fail if they target a path outside the allowlist. If you want to prevent the agent from *attempting* file edits in the first place, combine sandbox mode with `--approval-mode default` or `--approval-mode plan`.

**Q: Will sandbox mode slow down the AI?**

A: Negligibly on macOS (Seatbelt adds no measurable overhead). Container-based backends (Docker/Podman) have a startup cost of a few seconds on first use, but subsequent operations run at normal speed.

**Q: Does sandbox mode protect against prompt injection attacks?**

A: It reduces the impact. Prompt injection attacks that attempt to exfiltrate files or modify the filesystem outside the working directory will be blocked by the OS. However, actions within the allowed write paths are still possible. Always review AI responses critically, especially when working with untrusted input.

**Q: Can I enable sandbox mode by default for all sessions?**

A: Yes. Set `"sandbox": true` in `~/.tabnine/agent/settings.json` under the `"tools"` section.

**Q: Can I customize which paths are writable inside the sandbox?**

A: Yes, via two mechanisms: pass `--include-directories /your/path` on the CLI (up to 5 paths), or set `"allowedPaths"` in the object form of `tools.sandbox` in `settings.json`.

**Q: Can I use my own container image?**

A: Yes. Set `TABNINE_SANDBOX_IMAGE` to your image name, or set the `"image"` field in the object form of `tools.sandbox` in `settings.json`. The image name must consist of alphanumeric characters, dots, colons, hyphens, underscores, and forward slashes only.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tabnine.com/main/getting-started/tabnine-cli/features/sandboxing.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
