Runtime

How to run Goose in a cloud sandbox

Install the goose CLI with its download script in a Linux microVM, set provider and model by environment, and run goose run -t.

Runtime gives goose a disposable Linux machine and removes the keyring problem at the same time. goose's Docker guide notes that its keyring settings do not work on Ubuntu in a container and has you pass the API key as an environment variable instead. On Runtime that variable holds only a placeholder: the key is a Runtime secret, and the host's proxy adds the real value on requests to the provider. Every sandbox is a Firecracker microVM with its own kernel and Ubuntu 24.04. While goose waits on the model, 2 vCPUs and 4 GiB cost $0.03125 an hour. The newest stable tag on 25 September 2026 was v1.52.0.

Direction goose runs Runtime is
Headless task on a repo In a sandbox The machine, driven by the SDK
goose session on your laptop On your machine A stdio extension with sandbox tools

Store the provider key

goose reads provider settings from the environment: GOOSE_PROVIDER, GOOSE_MODEL, and the provider's own key variable, which for Anthropic is ANTHROPIC_API_KEY. Only the key is sensitive, so only the key becomes a secret:

Terminalprintf %s "$ANTHROPIC_API_KEY" | npx withruntime secrets set ANTHROPIC_API_KEY --host api.anthropic.com

Each sandbox of your account now starts with ANTHROPIC_API_KEY set to a placeholder. GOOSE_DISABLE_KEYRING tells goose not to look for a system keyring, and the proxy puts the real key on HTTPS requests to api.anthropic.com only (secrets sandboxes never see). Any other provider goose supports works the same way with its own variable and host.

A headless run from your code

TypeScriptimport { writeFile } from "node:fs/promises";import { Sandbox } from "withruntime";const repo = "https://github.com/your-org/your-repo";const task =  "Upgrade the project to the current major version of its test runner and fix what breaks.";const installGoose =  "curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash";await using sbx = await Sandbox.create({ diskMiB: 8192, timeoutSeconds: 3600 });const once = { check: true, timeoutMs: 600_000 } as const;await sbx.exec("sudo apt-get update && sudo apt-get install -y bzip2", once);await sbx.exec(installGoose, once);await sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"], once);// goose is installed; from here it may reach the model API and nothing else.await sbx.network.set({ internet: true, allow: ["api.anthropic.com"] });const run = await sbx.exec(  [    "goose",    "run",    "--no-session",    "--with-builtin",    "developer",    "--output-format",    "json",    "--max-turns",    "60",    "-t",    task,  ],  {    cwd: "/workspace/app",    env: {      GOOSE_PROVIDER: "anthropic",      GOOSE_MODEL: "claude-sonnet-4-5-20250929",      GOOSE_MODE: "auto",      GOOSE_DISABLE_KEYRING: "1",      GOOSE_DISABLE_SESSION_NAMING: "true",    },    timeoutMs: 1_800_000,    onStderr: (text) => process.stderr.write(text),  },);console.log(run.exitCode, JSON.parse(run.stdout));await sbx.exec("git add -A && git diff --cached > /workspace/goose.patch", {  cwd: "/workspace/app",  check: true,});await writeFile("goose.patch", await sbx.files.readText("/workspace/goose.patch"));
Pythonimport sys, jsonfrom withruntime import Sandboxrepo = "https://github.com/your-org/your-repo"task = "Upgrade the project to the current major version of its test runner and fix what breaks."install_goose = ("curl -fsSL https://github.com/aaif-goose/goose/releases/download/"                 "stable/download_cli.sh | CONFIGURE=false bash")with Sandbox.create(disk_mib=8192, timeout_seconds=3600) as sbx:    sbx.exec("sudo apt-get update && sudo apt-get install -y bzip2",             check=True, timeout_ms=600_000)    sbx.exec(install_goose, check=True, timeout_ms=600_000)    sbx.exec(["git", "clone", "--depth", "1", repo, "/workspace/app"],             check=True, timeout_ms=600_000)    sbx.network.set(internet=True, allow=["api.anthropic.com"])    run = sbx.exec(        ["goose", "run", "--no-session", "--with-builtin", "developer",         "--output-format", "json", "--max-turns", "60", "-t", task],        cwd="/workspace/app",        env={            "GOOSE_PROVIDER": "anthropic",            "GOOSE_MODEL": "claude-sonnet-4-5-20250929",            "GOOSE_MODE": "auto",            "GOOSE_DISABLE_KEYRING": "1",            "GOOSE_DISABLE_SESSION_NAMING": "true",        },        timeout_ms=1_800_000,        on_stderr=sys.stderr.write,    )    print(run.exit_code, json.loads(run.stdout))    sbx.exec("git add -A && git diff --cached > /workspace/goose.patch",             cwd="/workspace/app", check=True)    with open("goose.patch", "w") as file:        file.write(sbx.files.read_text("/workspace/goose.patch"))

Step by step:

  • bzip2 comes first because the Linux release is a .tar.bz2; goose's install guide suggests installing it when extraction fails.
  • CONFIGURE=false skips the interactive goose configure step. The script installs to $HOME/.local/bin, which in a sandbox is /workspace/.local/bin, already first on PATH.
  • The allow list is one host. goose ships as a single binary, so once it is installed it needs no package registry. Add the registries your project's tests install from.
  • --with-builtin developer loads goose's built-in developer extension, which gives it shell and file editing. With no config file, nothing else is loaded.
  • GOOSE_MODE=auto lets goose run tools without asking, and GOOSE_DISABLE_SESSION_NAMING saves the extra model call goose otherwise makes to name the session.
  • --no-session writes no session file; --max-turns caps the turns taken without user input (the default is 1000).
  • --output-format json returns the result once the run completes; use stream-json to watch events as they happen.

goose run options worth knowing

From goose's CLI command reference, 25 September 2026:

Option Purpose
-t, --text <TEXT> The instruction
-i, --instructions <FILE> Instructions from a file
--recipe <FILE> A recipe with a prompt field, for repeatable jobs
--provider, --model Override GOOSE_PROVIDER and GOOSE_MODEL
-q, --quiet Print only the model's response
--output-format json, stream-json Structured output after or during the run
--max-tool-repetitions <n> Stops identical tool calls repeating in a loop

A recipe is the goose way to repeat a job across many repos: one YAML file holds the prompt, instructions and extensions, and each sandbox runs goose run --recipe. Keep a checkout between recipes by pausing the sandbox rather than stopping it.

Add Runtime as a goose extension

goose calls MCP servers extensions. To give a goose session on your laptop Runtime's tools for one run:

Terminalgoose session --with-extension "runtime:npx -y withruntime mcp"

The runtime: prefix names the extension, so its tools appear as runtime__runtime_sandbox_create and so on rather than under npx. To keep it, add a stdio extension to ~/.config/goose/config.yaml:

YAMLextensions:  runtime:    type: stdio    name: runtime    enabled: true    cmd: npx    args: ["-y", "withruntime", "mcp"]    envs: {}    env_keys: []    timeout: 300

The first Runtime call prints a link and a code; approve Connect agent in the browser and every tool loads, with no key in the YAML (MCP). goose also takes remote servers as streamable_http extensions, which fits https://api.withruntime.com/mcp.

Tool What goose gets
runtime_sandbox_create A fresh microVM, ready when the call returns
runtime_sandbox_exec Commands run away from your laptop
runtime_sandbox_desktop_screenshot A look at a desktop running in the sandbox
runtime_secrets_set Keys for the sandbox to use without seeing

Cost

Runtime charges for CPU a sandbox actually uses, $0.025 per vCPU-hour with a floor of a twentieth of a vCPU, and $0.0075 per GiB-hour for reserved memory. A 2 vCPU, 4 GiB goose run is $0.03125 an hour while the model is working and $0.08 an hour at full CPU (pricing). The model provider bills tokens on your key. The trial has 50 free sandbox hours, no card needed:

Terminalnpx withruntime sandbox run --trial -- uname -a

Other open agents on Runtime: OpenCode and OpenHands. For many repos at once, see a sandbox for coding agents.

Sources

Checked 25 September 2026.

Facts on this page were checked on 25 September 2026.