# Sandbox

Code that your agent runs in its sandbox can call a connector's API with the connection's account. For instance, to count every open issue that mentions login, your agent can page through them with a short Python program. For the sandbox itself, see [Harness and sandbox](https://getstream.io/agents/docs/harness-and-sandbox/#sandbox).

## Let code call GitHub

Set `sandbox: true` on the connector's entry. The agent needs a sandbox too:

```yaml title="agents/support/agent.yaml"
name: support
mode: text
llm: llm-fast
sandbox: daytona
connectors:
  - name: github
    connection: company # the label of a connection the app owns
    sandbox: true # code in the sandbox may call GitHub's API
```

>
> **Warning:** An organization on the "not-verified" tier cannot do this. Stream refuses the save with an error that says the tier allows sandboxes no network. Leave `sandbox: true` off: the sync works, and `getstream agents tools` shows `SANDBOX no`.
>

In the Dashboard, the same two settings are on the agent's **Tools** tab: **Run code** under **Built-in tools**, and **Use in Run code** when you add or edit the connector.

Code that the agent runs with `run_code` now reads `GITHUB_TOKEN`. Its value is a placeholder, not the token. When the code sends the placeholder to GitHub, Stream puts the connection's token in its place on the way out. The code and the model never see the token.

>
> **Info:** Of the SDKs, only Go and JavaScript sync `sandbox` on a connector from `agent.yaml`. `getstream agents sync` syncs it too.
>

## Worked example

This code, run by the agent, prints the GitHub login of the connection's account:

```python
import json
import os
import urllib.request

request = urllib.request.Request(
    "https://api.github.com/user",
    headers={
        "Authorization": "Bearer " + os.environ["GITHUB_TOKEN"],
        "User-Agent": "support-agent",
    },
)
with urllib.request.urlopen(request) as response:
    print(json.load(response)["login"])
```

## Where the placeholder works

| Connector | Env var        | Hosts                                                |
| --------- | -------------- | ---------------------------------------------------- |
| `github`  | `GITHUB_TOKEN` | `api.github.com`, `uploads.github.com`, `github.com` |

- The placeholder works only in a request header, over HTTPS, to one of these hosts. Anywhere else, such as in the URL's path or query or to another host, it stays a placeholder and gets no access.
- Code reaches these hosts even when `allowed_domains` does not list them.
- Code only reads through a connector. A write is refused, such as `git lfs push`.

>
> **Warning:** Code can read anything the token allows, not only what the entry's `tools` offers.
>

### Git over HTTPS

git takes the placeholder as the password in the remote's URL, with `x-access-token` as the user name. GitHub refuses a Bearer header from git, so use this form for `github.com`:

```python
import os
import subprocess

url = f"https://x-access-token:{os.environ['GITHUB_TOKEN']}@github.com/<owner>/<repo>.git"
print(subprocess.run(["git", "ls-remote", url], capture_output=True, text=True).stdout)
```

### Git LFS

The sandbox has no Git LFS. To pull a repository's large files, install it in the sandbox's `setup`:

```yaml title="agents/support/agent.yaml"
sandbox: daytona
sandbox_options:
  setup:
    - apt-get update && apt-get install -y git-lfs
```

Code can then run `git lfs pull` in a clone of a public repository made with the URL above.

## Turn it off

Remove `sandbox: true` from the entry, remove the entry, or delete the connection. Within a minute, the next code the agent runs gets no access, even in a conversation already running. A program already running keeps it until it ends.

## Going further

- [Harness and sandbox](https://getstream.io/agents/docs/harness-and-sandbox/): The sandbox, and what code in it may reach.
- [Connectors](https://getstream.io/agents/docs/connectors/): What a connector is, a quickstart, and whose account it uses.

---

For the most recent version of this documentation, visit [https://getstream.io/agents/docs/connectors/sandbox/](https://getstream.io/agents/docs/connectors/sandbox/).