Documentation

Run OpenClaw in a Syva sandbox

A practical end-to-end pattern for testing OpenClaw away from your laptop: build a Node image, create a Syva sandbox, run OpenClaw onboarding, execute an agent turn, and cleanly destroy the sandbox.

Why sandbox it

OpenClaw is designed to run a Gateway that can receive messages, call a model provider, and use local tools. That is useful, but it is also exactly the kind of agent process you may not want to run directly on your main workstation while you are experimenting.

Syva gives the process a fresh Linux sandbox with a bounded CPU and memory budget. The agent still has outbound network access in this example, so treat any provider keys and connected accounts as real credentials.

What runs where

Your local machine runs the Syva Python SDK. Syva builds an image from node:24-bookworm-slim, installs openclaw@latest, and launches a sandbox with the provider credentials passed as environment variables. Inside the sandbox, the script runs non-interactive OpenClaw onboarding and then uses openclaw agent --local --json for one embedded agent turn.

This example uses OpenAI API-key onboarding because OpenClaw documents an env-backed SecretRef flow for it. Use the equivalent non-interactive OpenClaw flags for another provider if that is what your team uses.

Set up locally

Create a working directory and install the public Syva SDK.

Terminal
python -m venv .venv
source .venv/bin/activate
pip install syva python-dotenv

Generate a Gateway token locally, then place the token and API keys in .env.local.

Terminal
python -c 'import secrets; print(secrets.token_urlsafe(32))'
.env.local
SYVA_API_KEY=syva_...
OPENAI_API_KEY=sk-...
OPENCLAW_GATEWAY_TOKEN=replace-with-a-long-random-token

Launch OpenClaw

Save this as run_openclaw.py. It uses only the public Syva SDK: Image,Sandbox.create, sandbox environment variables, file-backed cleanup state, and foreground command execution.

run_openclaw.py
import os
from pathlib import Path

from dotenv import load_dotenv
from syva import Image, Sandbox

load_dotenv(".env.local")

missing = [
    name
    for name in ("SYVA_API_KEY", "OPENAI_API_KEY", "OPENCLAW_GATEWAY_TOKEN")
    if not os.environ.get(name)
]
if missing:
    raise SystemExit(f"Missing required environment variables: {', '.join(missing)}")

image = (
    Image.from_registry("node:24-bookworm-slim")
    .apt_install(["ca-certificates", "curl", "git", "python3", "make", "g++"])
    .run_cmd("npm install -g openclaw@latest")
    .workdir("/workspace")
)

sandbox = Sandbox.create(
    image=image,
    cpu_cores=2,
    memory_mb=4096,
    network_policy="allow-all",
    labels={"workflow": "openclaw", "mode": "local-agent"},
    env={
        "OPENAI_API_KEY": os.environ["OPENAI_API_KEY"],
        "OPENCLAW_GATEWAY_TOKEN": os.environ["OPENCLAW_GATEWAY_TOKEN"],
        "OPENCLAW_HOME": "/workspace/openclaw-home",
        "OPENCLAW_STATE_DIR": "/workspace/openclaw-state",
    },
)

try:
    setup = sandbox.run_command(
        "openclaw onboard "
        "--non-interactive "
        "--mode local "
        "--auth-choice openai-api-key "
        "--secret-input-mode ref "
        "--gateway-auth token "
        "--gateway-token-ref-env OPENCLAW_GATEWAY_TOKEN "
        "--accept-risk "
        "--skip-health "
        "--skip-bootstrap",
        cwd="/workspace",
        timeout_ms=240_000,
    )
    if setup.exit_code != 0:
        raise RuntimeError(setup.stderr or setup.stdout)

    result = sandbox.run_command(
        "openclaw agent "
        "--session-key syva-demo "
        '--message "Reply with exactly one sentence: OpenClaw is running inside Syva." '
        "--local "
        "--json",
        cwd="/workspace",
        timeout_ms=300_000,
    )
    if result.exit_code != 0:
        raise RuntimeError(result.stderr or result.stdout)

    Path(".openclaw-syva-sandbox").write_text(sandbox.id + "\n")
    Path("openclaw-result.json").write_text(result.stdout)
    print(f"Syva sandbox: {sandbox.id}")
    print("OpenClaw result written to openclaw-result.json")
    print(result.stdout)
except Exception:
    sandbox.destroy()
    raise

Run it from the same directory as .env.local.

Terminal
source .venv/bin/activate
python run_openclaw.py

The command prints the sandbox id and the JSON response from OpenClaw. It does not print your provider key or Gateway token.

Read the result

The runner prints the OpenClaw JSON response and writes it to openclaw-result.json. Keep the sandbox id in .openclaw-syva-sandbox if you want to inspect the same sandbox withSandbox.get before cleanup.

Stop it

The sandbox is intentionally temporary. Use it to verify OpenClaw configuration and run short experiments. When you are done, destroy the sandbox from your local machine.

Terminal
source .venv/bin/activate
python - <<'PY'
from pathlib import Path

from dotenv import load_dotenv
from syva import Sandbox

load_dotenv(".env.local")

path = Path(".openclaw-syva-sandbox")
sandbox_id = path.read_text().strip()
Sandbox.get(sandbox_id).destroy()
path.unlink(missing_ok=True)
print(f"Destroyed {sandbox_id}")
PY

References

Current limitations

  • OpenClaw config, sessions, and memory stored inside the sandbox are removed when the sandbox is destroyed.
  • Syva does not currently provide persistent volumes, so this is a test and evaluation pattern rather than a durable OpenClaw home.
  • Syva does not currently expose GPU scheduling. Run OpenClaw against hosted model APIs or an external model endpoint, not a local GPU model inside the sandbox.
  • The OpenClaw browser Control UI depends on Gateway connectivity. This example uses a CLI agent turn because Syva public docs only promise declared HTTP previews, not a tested browser Gateway session.
  • Declare preview ports at sandbox create time for HTTP servers you do expose. Syva does not currently provide public custom-domain ingress.