Skip to main content

Goose AI Agent Sandbox

A Goose sandbox from Cosmonic runs Block's Goose agent where it cannot reach your files, your network or your API keys. Cosmonic Desktop does this on its Agents page: Goose's own agent loop, patched to build for WASI, is compiled to a WebAssembly component that imports no network and no filesystem. Desktop makes every model call, and each tool Goose calls is a separate component with its own grant. The same image, ghcr.io/cosmonic/agents/goose, deploys to Kubernetes with Cosmonic Control.

Why sandbox Goose​

Goose does its work through extensions, and extensions are MCP servers. A command-line extension is a program Goose starts on your machine, with your user's permissions, your files and your network. Goose's permission modes decide when Goose asks before it uses a tool, from fully autonomous to approve each call. They do not limit what a tool can reach once it runs.

A sandbox moves that boundary. In the Cosmonic sandbox each tool is its own component, granted one folder or a short list of hosts, and Goose's loop itself has no network and no key.

Run Goose in a sandbox in Cosmonic Desktop​

1. Start a Goose session​

  1. In Desktop, select Agents under AI & agents in the sidebar. If you already have sessions, select New.
  2. Select the agent chip next to the message box and choose Goose.
  3. Select the Model chip. Choose a source (such as Ollama on this machine, or Add a source… to enter an API key), choose a model, then select Done. Desktop keeps the key; Goose asks the host for a model by its alias and never sees it. See Choose the model.

2. Give Goose a folder​

Goose has no files of its own. To let it work on a project, choose one folder:

  1. Select the folder chip under the message box, which shows No folder, then Choose a folder…, and pick the folder.
  2. Select the access chip next to it and choose Read only, Edit with undo or Ask before each edit.

Desktop adds the folder tools that match: Workspace (read) always, git when the folder is a git repository, and Workspace (write) unless you chose Read only. Each one sees that folder and nothing outside it.

3. Add tools and start​

Tools take the place of Goose extensions. Each is a component with its own reach, listed on its card.

  1. Select Tool settings…, then Add tools yourself…, find a tool in Search tools, and select Add.
  2. To approve each host the first time a tool reaches it, turn on Ask first before a tool reaches each host.
  3. Select Done, type your first message, and start the session.

To bring an MCP server you already use with Goose, add it to the catalog in Settings → Tools with Add a tool: as an MCP server built as a component, or as a Remote MCP server that needs no sign-in. See Sandbox MCP Servers for turning a local MCP server into a component.

Goose streams its reply as the model writes it, and when it keeps a to-do list, Desktop shows it as the session's plan.

4. Check what Goose can reach​

Select Show session details in the session header. This session can… lists each kind of reach (Change files in a folder, Read a folder, Reach hosts) with the tool that grants it. Select a tool to see every call Goose made through it.

The full set of tool and host options is in Give an agent a tool.

Run Goose on Kubernetes with Cosmonic Control​

The Goose image exports cosmonic:agent/run, so Control drives it the same way as any other agent harness. Follow Run an agent on Control and use the Goose image for the agent component:

components:
  - name: agent
    image: ghcr.io/cosmonic/agents/goose@sha256:cddcd4d2b7dbf684f67a48e9f137c1c3cd29dfdbc6ac729b8b9820b78c5d27fb # 0.41.0, the release Desktop runs
    localResources:
      allowedHosts: []

The agent keeps allowedHosts: []. Tools are their own components in the same workload, each with its own hosts or volume; see Give an agent a tool. Runs start over HTTP with the OpenAI Responses API or over NATS, and the workload spec goes through the same RBAC and admission policy as your other manifests.

What sandboxed Goose can reach​

The Goose component imports these interfaces from cosmonic:agent, and nothing else that reaches outside it:

  • inference-types, models and chat: a model, by an alias the host resolves. The host makes the call with credentials Goose never holds. Goose does not import the model catalog, so it cannot list models or force one to load.
  • tools: the tools the session or workload grants.
  • session: the conversation and a journal of every step and tool call, kept by the host.

Outgoing HTTP, sockets and the filesystem are absent from the compiled component, not blocked by a policy. Desktop reads an agent's imports before it runs it and refuses one that imports the network or the filesystem.

What changes from the Goose app​

  • The loop is Goose's. The component runs Goose's own StateMachine and InferenceRunner, with a provider that answers through the host instead of an HTTP client. It registers two steps, tools and inference, where the full Goose application registers eighteen.
  • Extensions become tools. Goose's built-in and command-line extensions are not in the component. The host serves the tools a session grants, and each one runs as its own component.
  • The to-do list is Goose's. Goose's todo_write tool keeps its upstream name and schema; it is answered inside the component and streams to Desktop as the plan.
  • Compaction is Goose's. Goose's context-management code summarizes the conversation at 90 percent of the model's window (upstream's default is 80).
  • The host keeps the conversation. The component holds nothing between turns, so a session survives restarts and a run on Control can be served by another replica.

Goose sandbox or a container?​

Running Goose in Docker or a VM puts one wall around Goose and every extension it starts. They share the box, its network and your provider key, so one extension can reach anything another one can.

The Cosmonic sandbox splits those parts. Goose's loop has no network and no key. Each tool has its own grant: one folder, or a short list of hosts. An MCP server that misbehaves can reach only what its own grant allows, and the record of what it was called with is in the session.

Frequently asked questions​

How do I sandbox the Goose AI agent?

Install Cosmonic Desktop, open Agents, select New, and choose Goose in the agent chip. Goose’s agent loop then runs as a WebAssembly component with no network, files or API keys of its own, and reaches only the folder and tools you grant.

Does Goose itself run inside the sandbox?

On Desktop’s Agents page and on Cosmonic Control, yes: Goose’s agent loop is the sandboxed component, and the host makes every model call and tool call for it.

Can I use my Goose extensions in the sandbox?

Not as native extensions. In the sandbox, tools come from Desktop’s catalog, and each one runs as its own component with its own grant. An MCP server can join the catalog as a component or as a remote MCP server that needs no sign-in.

Is this the same Goose as Block’s?

It is Block’s upstream Goose state machine, inference runner and context management, patched to build for WASI, with Goose’s to-do tool under its upstream name and schema. The Goose desktop app, its extensions and its own provider clients are not part of the component; the host supplies the model and the tools.

Where are my API keys when Goose runs in the sandbox?

With the host. Goose asks Desktop or Control for a model by an alias such as default, and the host makes the call with a key Goose never sees. On Desktop the key stays in your system keychain or the secret store you chose; on Control it is a Kubernetes secret.

Can I run the same Goose agent on Kubernetes?

Yes. Deploy the ghcr.io/cosmonic/agents/goose image as the agent component of a Cosmonic Control workload. It keeps no network of its own, and its tools are separate components with their own grants in the same manifest.

Next steps​