Sandboxing AI: Run Agent-Generated Code in an AI Sandbox
Walkthrough 1 ran a component someone else built. This one runs code an AI writes for you—and puts it somewhere it can't hurt you. You'll go from a one-line prompt to a running workload in an AI sandbox: a WebAssembly isolate whose reach is decided before the code ever starts, not after it misbehaves.
Why agent-generated code needs a sandbox
An agent that can write code can write code you didn't read. The failure modes aren't exotic: a dependency with a postinstall script, a prompt injection carried in a web page the agent fetched, a plausible-looking command that deletes the wrong directory. What they have in common is that they all execute with your privileges the moment the agent runs them on your host.
The fix isn't to trust the agent harder. It's to give its output a smaller world to live in. Every workload Desktop runs is a WebAssembly component with no ambient authority: it gets exactly the capabilities its spec grants and nothing else. No filesystem unless you grant one. No outbound network unless you list the hosts. That boundary is identical whether the code came from you, from a registry, or from a model, which is what makes it worth trusting.
This page is about sandboxing the code an agent writes. Desktop also sandboxes the tool servers an agent calls—see Sandbox MCP Servers. Both land in the same deny-by-default runtime.
Before you start
- Finish Walkthrough 1: Run your first workload so the host is running and you've seen the review-and-apply step.
- Install at least one coding agent CLI and its cosmonic-sandbox skill. Desktop offers to install the skill for every agent it detects on first run; you can also do it any time under Settings → Agent skills. See Connect Coding Agents for the per-agent details.
- Builder only offers agents whose skill is installed and whose binary resolves on your login
PATH. If the dropdown is empty, that's why. - Builder points you in the right direction; with the integrated MCP server, you can already interact with Cosmonic Desktop from your favorite dev tools, IDE, CLI, or other platforms.
1. Open Builder
Open Cosmonic Desktop and click the Builder button in the header. The Builder opens as a drawer beside your current view—Desktop opens to Workloads—so you can start a build without leaving the app's home view.
The How does this work? button in the top right replays the intro animation above. As in walkthrough 1, wait for the status bar to report the host running before you launch anything.
2. Describe what you want built
Type what you want in plain language. The example chips under the box are real prompts—click one to fill the box:
an image resize API — upload a photo, store it in blob storage, return a 256px thumbnailTwo fields below the prompt shape what gets created:
project-name— a DNS label (lowercase letters, digits, hyphens). This names the directory, the component, and the workload. Each project gets its own directory under your projects folder (~/cosmonic-projectsby default, configurable in Settings → Project folders); the path preview to the right shows exactly where it lands.Template— the starter the repo is cut from: Rust HTTP, Go HTTP, TypeScript HTTP, or Auto. Leave it on Auto and Builder infers the language from your prompt—mention "in Go" and you getgo-http. The Auto label live-previews which template your current prompt would select, and Rust wins on a tie.
The starter is a working HTTP component, not an empty directory. The agent begins from something that already builds.
3. Choose the agent, model, and start mode
Three pickers decide how the agent runs:
The agent (top-left of the prompt box). Every agent whose skill is installed and whose binary is on your PATH. Hover an entry to open its model submenu—clicking a model picks the agent and the model in one gesture. Your choice persists across visits.
The start mode (bottom-left, with a colored risk badge). This is the important one: it decides how much the agent may do without asking. Every agent exposes its own modes, and the badge tells you which boundary you're behind:
| Badge | Means |
|---|---|
| Guarded | No prompts for routine work, but a guardrail stays in the loop—a classifier reviewing each action, or the agent's own workspace sandbox. |
| Asks first | Plan-first or per-action approval. Nothing runs until you say so. |
| YOLO | Every permission prompt skipped. |
The default is always a guarded mode, never YOLO. For Claude Code that's Auto, where a classifier reviews each action and blocks escalation and hostile-content-driven behavior.
YOLO is not reckless here the way it is on a bare host—that's the point of the sandbox—but the agent still has your shell in the project directory. Bypass belongs to sessions whose blast radius you've already decided you can live with.
The terminal (bottom-right). Desktop detects the terminal apps you have installed and preselects your likely daily driver. The agent opens in a new window of that app as an independent process—quitting Desktop won't kill it.
The $ … line at the bottom of the box is the literal argv that will be spawned. What you see there is what runs, including the (on cosmonic desktop) suffix Builder appends to your prompt so the agent picks up its cosmonic-sandbox skill.
4. Launch
Press Enter (or click the ↑ button). Builder scaffolds the project from the template into <projects-dir>/<project-name>, then opens your terminal with the agent already running in that directory, your prompt carried over.
The scaffold refuses a non-empty directory, so a name collision fails loudly instead of writing into an existing project.
5. Watch the agent build inside the sandbox
From here the agent works on its own, driving Desktop through the MCP server the daemon runs by default. The loop it follows:
- It writes the handler code with its own file tools—Desktop's tools never write your source.
cosmonic_devbuilds the component and runs it in a watch loop;cosmonic_dev_logsfeeds compile and runtime errors back so the agent can fix them without you relaying output.cosmonic_promotedoes a fresh build, pushes the component, and returns a digest-pinned image reference plus a ready-to-apply Workload draft—withallowedHostsdefaulting to deny-all.cosmonic_apply_workloadschedules it. The workload shows up in your Workloads view, sandboxed exactly like the one you applied by hand in walkthrough 1.
Two guardrails hold regardless of which agent is driving and which mode it's in: destructive operations require an explicit confirm, and secrets are registered as references (keychain, 1Password, AWS, env) so the agent never handles a value.
Your projects are listed under the prompt box with live build and run status. Clicking one reopens it in the same agent and terminal, which is how you get back into a session after closing the window.
6. Review the sandbox the agent asked for
This is the step worth slowing down for. Expand the workload's row in Workloads and read what the agent actually asked for:
- The image is digest-pinned. The tag resolved to an immutable digest at apply time, and that digest is what runs. Re-pushing the tag doesn't change the running code.
- Egress is deny-by-default.
allowedHostsstarts empty. If your prompt needed an outbound call, the agent had to name the host—so the list is a readable summary of every external service the code can reach. - Capabilities are inferred from the component's interfaces, not from what the agent claims. A component that never imported
wasi:filesystemcannot open a file, no matter what its README says. (Walkthrough 3 shows this at the binary level.) - Secrets are references. Values live in your keychain or password manager; the spec carries a pointer.
- The Signed column reports cosign signature status. Locally-built components are unsigned, and the default policy admits them with a warning; Settings → Security can require verified signatures instead.
If something in that list looks wrong, it's wrong before it can matter. That's the whole trade the review step buys you.
7. Call it, then clean up
Reach the workload through Desktop's built-in ingress, which listens on 127.0.0.1:8200 and routes by hostname:
curl http://<project-name>.localhost:8200/On systems whose resolver doesn't handle .localhost subdomains, send the hostname as a header instead:
curl -H 'Host: <project-name>.localhost' http://127.0.0.1:8200/The Logs view streams the daemon's event log—pulls, verifications, starts, failures—if the response isn't what you expected. When you're done, stop or delete the workload from its detail view. Deleting removes the spec; the pulled image stays in the local content-addressed cache for instant reuse, and the project directory stays on disk.
What you actually built
A workload spec in plain YAML, on disk under the app's state directory, in the same runtime.wasmcloud.dev/v1alpha1 schema Cosmonic Control runs on Kubernetes. It's git-able, reviewable in a pull request, and deploys to a cluster unchanged—see From laptop to cluster.
Which means the sandbox isn't a local-development affordance you outgrow. The boundary you reviewed on your laptop is the boundary that ships.
Frequently asked questions
What is an AI sandbox?
An AI sandbox is an isolated execution environment for code written or run by an AI agent, where the code gets an explicit, reviewable set of capabilities instead of inheriting the privileges of the user who launched the agent. Cosmonic Desktop implements one with WebAssembly components: each workload runs with no ambient authority, no filesystem or network access unless its spec grants it, and a digest-pinned image so the code that was reviewed is the code that runs.
How do I sandbox AI agents on my own machine?
Install Cosmonic Desktop, install the cosmonic-sandbox skill into your coding agent from Settings → Agent skills, and launch the agent from Builder. The skill teaches the agent to deploy what it generates into the local WebAssembly sandbox instead of running it directly on your host, and Desktop's MCP server gives it the tools to do so. The agent still runs in your terminal; what changes is where its output executes.
Is sandboxing AI-generated code different from running it in a container?
Yes, in what is granted by default. A container starts with a filesystem, a network namespace, and a process tree, and you harden it by taking things away. A WebAssembly component starts with nothing and can only do what its declared interfaces allow, so the capability list is derived from the binary rather than asserted in configuration. Components also start in milliseconds and idle at near-zero cost, which matters when an agent is deploying dozens of iterations.
Does the coding agent itself run inside the sandbox?
No. The agent runs as a normal process in your own terminal, with whatever permissions its start mode allows — that is what the Guarded, Asks first, and YOLO badges in Builder describe. The sandbox applies to the workloads the agent deploys. Choosing a guarded start mode and sandboxing the deployed output are complementary controls, not substitutes.
What stops agent-generated code from calling out to the internet?
Outbound network access is deny-by-default: a workload's allowedHosts list starts empty and the component can only reach hosts named in it. An agent that needs an external API has to add that host to the spec, which means every external dependency shows up in the draft you review before applying.
Which coding agents work with Builder?
Claude Code, OpenAI Codex, Gemini CLI, Google Antigravity, and Hermes Agent can be launched directly from Builder. Any MCP client, including Cursor and Zed, can drive Desktop over the same stdio MCP server without going through Builder. OpenClaw and NVIDIA OpenShell integrate through the MCP server rather than the Builder launcher.
Next steps
- Walkthrough 3: Build an AI sandbox from scratch — drop the app entirely and build the same kind of component by hand with
wash, so you can see the capability boundary in the binary. - Sandbox the tool servers your agents call in Sandbox MCP Servers.
- Per-agent setup, the full
cosmonic_*tool list, and the skill layout: Connect Coding Agents. - Tour the rest of the app in Application Views.
- Hit a snag? See Troubleshooting.