Skip to main content
Most sandboxes are short-lived: an agent framework or evaluation harness creates one, runs a task, and discards it. A development sandbox, or dev box, inverts that. You create one sandbox deliberately, keep it for hours, and work inside it from your terminal. This tutorial builds a dev box that runs Claude Code against a repository. It then shows you how to reattach to the same sandbox from a shell and retrieve the results.
CoreWeave sandboxes are in public preview. For access, contact your CoreWeave account team, CoreWeave Support, or email support@coreweave.com.

What you build

By the end of this tutorial, you have all of the following:
  • A sandbox with an explicit multi-hour lifetime and outbound internet access.
  • Claude Code installed and authenticated inside it.
  • A shell attached to the running sandbox from your own terminal.
  • The agent’s output copied back to your machine.
The most important step is the lifetime. A sandbox created without max_lifetime_seconds runs for at most 10 minutes, which is enough for a batch task and far too short for a dev box.

Prerequisites

Before you start, make sure you have the following:
  • A sandbox runner in the Ready state. To deploy one, see Get started with CoreWeave sandboxes.
  • A CoreWeave API access token exported as CWSANDBOX_API_KEY.
  • An Anthropic API key for Claude Code. Get one from the Anthropic Console.
  • The cwsandbox SDK with the CLI extra installed. The CLI ships separately from the core SDK, and you need it to reattach to the sandbox later:
Set both credentials in your shell. Replace [COREWEAVE-API-TOKEN] with the Token Secret from the Tokens page, and [ANTHROPIC-API-KEY] with your Anthropic key:

Step 1: Find a profile with internet access

Claude Code calls the Anthropic API from inside the sandbox, so the sandbox needs outbound internet access. Sandboxes don’t get it by default: profiles determine which egress modes are available, and many deny all outbound traffic. List the profiles that permit internet egress:
Example output
If the list is empty, no profile you can reach allows internet egress. Ask whoever administers your runners to add one. For the guardrails involved, see Configure a sandbox profile. Note the profile name you want. The next step passes it explicitly so the sandbox doesn’t use a deny-all profile.
Egress mode names come from your profile configuration, not from a fixed list. internet is the conventional name for full outbound access, but your organization might use a different one. The names in p.egress_modes are the values you can pass.

Step 2: Create the sandbox with an explicit lifetime

Set three things when you create the sandbox: a lifetime long enough for a working session, internet egress, and your Anthropic key as an environment variable. Claude Code requires Node.js, so this tutorial starts from a node image. Replace [PROFILE-NAME] with the profile from Step 1:
create_devbox.py
Example output
Record the sandbox ID. You need it to reattach from another terminal. This example deliberately avoids a with block. A context manager stops the sandbox when the block exits. That’s the right behavior for a batch job and the wrong behavior for a dev box you want to keep. The sandbox also outlives the script that created it. The SDK’s exit and signal handlers stop sandboxes that belong to a Session, and Sandbox.run() doesn’t create one, so this sandbox keeps running after the Python process ends. That’s what makes the next steps possible from a separate terminal. It also means the lifetime you set is the only thing that eventually cleans it up.
Choose the lifetime now, because you can’t change it later. No API extends the lifetime of a running sandbox. When the lifetime expires, the platform terminates the sandbox immediately, without a grace period and without saving its filesystem. Anything you haven’t copied out is lost. Pick a value that comfortably covers your session, and copy work out as you go.

Step 3: Install Claude Code

Install the Claude Code CLI inside the running sandbox:
Installing at runtime keeps this tutorial self-contained, but it costs a minute or two on every new sandbox. If you create dev boxes regularly, build an image with Claude Code and your other tools already installed. Publish it to a registry your runner can pull from, then pass it as container_image instead. Confirm the CLI is on the path and can access its credentials:
Example output

Step 4: Give the agent something to work on

A dev box requires a workspace. Clone a repository into the sandbox, then let the agent work on it. Replace [REPOSITORY-URL] with the URL of the repository you want to clone:
Run Claude Code non-interactively with -p, which sends a single prompt and prints the response:
Give agent commands a generous timeout_seconds. The value bounds how long the client waits for that one command, and an agent working through a large repository can run for several minutes. Keep it below the sandbox’s remaining lifetime, because a command outliving its sandbox fails with it. To continue the same conversation across separate exec() calls, pass --continue. This example also has the agent write its answer to a file, which later steps read back:
The agent now leaves /workspace/notes.md behind in the sandbox. Step 6 copies it back to your machine.

Step 5: Reattach from your terminal

The cwsandbox CLI opens an interactive shell in a running sandbox from any terminal, including a different machine from the one that created it. Driving an agent through exec() calls works, but a dev box is more useful when you can work in it directly. Replace [SANDBOX-ID] with the ID from Step 2:
You get a TTY inside the sandbox, where you can run claude interactively:
Example output
Exit the shell with exit or Ctrl+D. Exiting the shell doesn’t stop the sandbox, so you can reconnect as often as you like while the lifetime lasts. Two other CLI commands are useful here:
A single shell session ends after 24 hours, even when the sandbox’s lifetime is longer. The sandbox keeps running, so if a long-lived session drops, reconnect with cwsandbox sh.

Step 6: Retrieve your work and stop the sandbox

Copy anything you want to keep back to your machine before the sandbox stops. read_file() returns bytes:
To send a file the other way, use write_file(), which also takes bytes:
When you finish, stop the sandbox explicitly rather than waiting for the lifetime to expire. A stop() gives processes inside the sandbox a grace period to exit cleanly, which expiry does not:
If you’ve lost the Python object, reattach by ID first, then stop it:
To find dev boxes you’ve lost track of entirely, use Sandbox.list() with the dev-box tag from Step 2. For more information, see Cleanup patterns.

What to know before you rely on a dev box

A few behaviors limit what a dev box can do:
  • The lifetime is fixed at creation. No extend operation exists. To keep working past the limit, copy your work out, then create a new sandbox with a longer lifetime.
  • Expiry is not a clean shutdown. The platform terminates the sandbox and its filesystem goes with it. Treat the sandbox as scratch space and keep anything durable in a repository or copied to your machine.
  • A reattached handle doesn’t report the remaining lifetime. A sandbox retrieved through Sandbox.from_id() or Sandbox.list() doesn’t carry its lifetime, so track when you created it yourself.
  • Credentials injected as environment variables are frozen at start. The sandbox’s ANTHROPIC_API_KEY is set once when the container starts and can’t be rotated in place. To change it, create a new sandbox.
  • Sandboxes have no idle timeout. Nothing stops a sandbox because you stopped using it. Only the lifetime or an explicit stop() ends it, so an unused dev box keeps consuming resources until its lifetime expires.

Next steps

  • Timeouts covers all four timeout settings and how they interact.
  • Sandbox lifecycle explains sandbox states, waiting, and shutdown in depth.
  • Interactive shells and TTY shows how to drive a TTY session from Python instead of the CLI.
  • Discovery covers filtering runners and profiles by capability and capacity.
  • Cleanup patterns shows how to find and stop sandboxes you’ve lost track of.
Last modified on August 13, 2026