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.
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
Readystate. 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
cwsandboxSDK with the CLI extra installed. The CLI ships separately from the core SDK, and you need it to reattach to the sandbox later:
[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
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 anode image. Replace [PROFILE-NAME] with the profile from Step 1:
create_devbox.py
Example output
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.
Step 3: Install Claude Code
Install the Claude Code CLI inside the running sandbox: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:
-p, which sends a single prompt and prints the response:
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:
/workspace/notes.md behind in the sandbox. Step 6 copies it back to your machine.
Step 5: Reattach from your terminal
Thecwsandbox 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:
claude interactively:
Example output
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:
write_file(), which also takes bytes:
stop() gives processes inside the sandbox a grace period to exit cleanly, which expiry does not:
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()orSandbox.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_KEYis 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.