Sandbox access

Some work is easier in code than with tools. For instance, to count every open issue that mentions login, your agent can page through them with a short Python program. Sandbox access lets that code call the connector's API with its connection, in the agent's sandbox.

Let code call GitHub

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

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

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:

Only the Go and JavaScript SDKs sync sandbox on a connector from agent.yaml.

Worked example

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

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 can read anything the token allows, not only what the entry's tools offers.
  • Code only reads through a connector. A write is refused, such as git lfs push.

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:

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:

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