> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tinfoil.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Bunker features

> Run coding agents, open a web terminal, connect services through your Perimeter, and use a remote desktop.

A Bunker is a full Ubuntu machine. You log in as the `sandbox` user, who has passwordless `sudo` and can run Docker. Your home directory, `/workspace`, and anything you install persist on the encrypted workspace volume across restarts.

## Running your coding agent

Popular coding agents come preinstalled, along with language toolchains, language servers, linters, databases, and cloud CLIs. They start with their normal provider selection and sign-in, so you can use your existing vendor account, as long as your Perimeter lets the Bunker reach that vendor.

To use [Tinfoil's private inference](https://docs.tinfoil.sh/models/overview.md) instead:

1. In your Perimeter, add the **Tinfoil** connection, keep its name `tinfoil`, and save your [Tinfoil API key](https://docs.tinfoil.sh/get-api-key.md) there.

2. Grant the Bunker access to it, including **Inference → Generate responses**, **List models**, and, for Claude Code, **Count input tokens**.

3. Copy the connection's substitution key (it starts with `tfm_tinfoil_`) and run this inside the Bunker:

   ```bash theme={"dark"}
   monitor enable tinfoil tfm_tinfoil_...
   ```

4. Choose Tinfoil in your agent, then restart any agent that was already running.

The substitution key is a placeholder, not your API key. Your Perimeter swaps in the real key on the way out; see [credential substitution](https://docs.tinfoil.sh/bunkers/perimeters.md#credential-substitution).

| Agent | Choose Tinfoil |
| - | - |
| OpenCode (`opencode`) | `/models` → Tinfoil, or `opencode --model tinfoil/<MODEL_NAME>` |
| Claude Code (`claude`) | `claude --settings /usr/local/share/tinfoil/claude.json` |
| Codex (`codex`) | `codex --profile tinfoil` |
| Crush (`crush`) | Tinfoil in the model picker |
| Qwen Code (`qwen`) | `/model` → a Tinfoil model, or `qwen --auth-type openai --model <MODEL_NAME>` |
| pi (`pi`) | `/model` → Tinfoil, or `pi --provider tinfoil --model <MODEL_NAME>` |
| Goose (`goose`) | Tinfoil in `goose configure`, or `goose session --provider tinfoil --model <MODEL_NAME>` |
| Droid (`droid`) | `/model` → Custom models → a model marked Tinfoil |
| GitHub Copilot (`copilot`) | `(. /usr/local/share/tinfoil/copilot.env; copilot)` |

Agents that read skills (Claude Code, Codex, OpenCode, and others) also get a `monitor` skill, so they know how to discover connections and ask you for access instead of asking for credentials.

### Installing more software

Use `apt`, Docker, or Nix as you would on any Ubuntu machine:

```bash theme={"dark"}
nix shell nixpkgs#jq
nix run nixpkgs#hello
```

A notable benefit of using Nix is that the environment already comes with most dependencies downloaded, so it can be faster than apt.

Downloads go through your Perimeter like all other traffic, so the package source must be reachable under your Perimeter's policy.

## Web terminal

Choose **Open in browser** on a Bunker's row in the [dashboard](https://dash.tinfoil.sh/?tab=sandboxes) for a shell in a browser tab. It is available when the Bunker and its Perimeter both use keys **synced with your passkey**.

The web terminal runs on `terminal.tinfoil.sh`. After you unlock your keys with your passkey, the page:

1. Verifies the Perimeter's attestation and opens an encrypted session to it, authenticated with your owner key.
2. Fetches the Bunker's attestation through the Perimeter and verifies it in the browser, including the Bunker image's Sigstore provenance.
3. Opens a second encrypted session, to the Bunker itself, inside the first. The Perimeter relays this session but sees only ciphertext.
4. Unlocks the workspace if needed, then starts your shell.

The web terminal is a shell, not an SSH server. For port forwarding, file transfer, or editor integrations, connect with SSH.

## SSH

`tinfoil attest-ssh <name> --install` writes a normal SSH profile, so anything that reads your SSH config works with the Bunker's name: `ssh`, `scp`, `rsync`, and remote-SSH editor extensions. The connection runs through the Perimeter, but SSH encrypts it end to end, and the profile pins the Bunker's attested host key.

## Perimeters

Your Bunker reaches the outside world only through its Perimeter. All TCP traffic, including DNS lookups, goes through an encrypted tunnel to the Perimeter, which then applies your policy. Traffic that matches no allowed connection is refused.

Inside the Bunker, the `monitor` command shows what the Perimeter allows:

```bash theme={"dark"}
# Services this Bunker can use, with their state and hosts
monitor connections

# Run a command with credential placeholders and proxy settings for one connection
monitor run --connection github -- gh repo list

# Serve the MCP connections granted to this Bunker on local ports
monitor mcp serve --listen 127.0.0.1:8400
```

Agents can ask for more access with `monitor policy propose`; you approve or deny each request in the Perimeter. See [Perimeters and access control](https://docs.tinfoil.sh/bunkers/perimeters.md).

## Remote desktop

`sandbox-desktop` starts a graphical Xfce desktop, streamed to your browser. It uses [Selkies](https://github.com/selkies-project/selkies) over WebSockets rather than the VNC protocol, and supports audio.

Start it inside the Bunker, as the `sandbox` user:

```bash theme={"dark"}
tmux new -s desktop sandbox-desktop
```

Running it in `tmux` keeps the desktop alive when you disconnect. Then forward its port from your computer and open `http://127.0.0.1:6080/`:

```bash theme={"dark"}
ssh -N -L 6080:127.0.0.1:6080 my-bunker
```

The desktop listens only on the Bunker's loopback address and has no password of its own; the SSH connection provides authentication and encryption. Graphics render on the CPU. Browsers inside the desktop reach the internet through your Perimeter, like everything else in the Bunker.

| Variable | Default | Purpose |
| - | - | - |
| `SANDBOX_DESKTOP_PORT` | `6080` | Loopback HTTP port |
| `SANDBOX_DESKTOP_SIZE` | `1600x1000` | Initial resolution |
| `SANDBOX_DISPLAY` | `:1` | X display |

Stop the desktop with Ctrl-C or **Log Out** in Xfce.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.