Cloud Sandbox Host

A cloud sandbox host moves the Omnigent runner from your laptop to a remote container. Your agent keeps working after you close your laptop, in an isolated environment with cloud compute.

Looking to restrict what your agent can access on the filesystem and network instead? That's Omnibox.

Local runnerCloud sandbox host
AvailabilityStops when laptop closesRuns independently
ComputeYour CPU and memoryCloud compute
EnvironmentLocal filesIsolated, reproducible
Best forInteractive workLong-running tasks

Omnigent currently supports Modal, Daytona, Blaxel, Islo, NVIDIA OpenShell, and Boxlite for cloud sandbox hosts.

The hosted-platform comparison below covers Modal, Daytona, Blaxel, and Islo. OpenShell connects to your selected gateway; Boxlite can use a local micro-VM runtime or a remote boxlite serve pool.

ModalDaytonaBlaxelIslo
Runner lifetime24 hours (platform cap)No cap (runs until deleted)24h max age by default (raise via ttl)No cap (idle-paused after 15 min when managed)
Credential injectionNamed secrets (Modal secret store)Env vars copied from serverEnv vars copied from serverEnv vars copied from server / gateway profile
Free-tier egressFull egressAllowlisted domains onlyFull egressGateway profile controls egress

Server-managed (recommended)

Configure your server once and anyone on the team can launch a cloud sandbox host from the web UI.

1. Install

pip install 'omnigent[modal]'       # for Modal
pip install 'omnigent[daytona]'     # for Daytona
pip install 'omnigent[blaxel]'      # for Blaxel
pip install 'omnigent[islo]'        # for Islo
pip install 'omnigent[openshell]'   # for OpenShell
pip install 'omnigent[boxlite]'     # for Boxlite

The Islo launcher uses the Islo Python SDK, which ships in the omnigent[islo] extra and is imported lazily, so only users of the Islo provider need to install it. The omnigent[blaxel] extra ships the Blaxel Python SDK with the same lazy-import posture. To launch Blaxel sandboxes from the CLI you also need the Blaxel CLI (brew tap blaxel-ai/blaxel && brew install blaxel).

2. Set provider credentials

Modal: run modal setup to authenticate, or set MODAL_TOKEN_ID and MODAL_TOKEN_SECRET on the server.

Daytona: create an API key in the Daytona dashboard (Dashboard > Keys) and set it on the server:

export DAYTONA_API_KEY=dtn_…

Islo: create an API key with the Islo CLI (islo login, then islo api-key create omnigent --show) and set it on the server. The SDK exchanges the key for short-lived session tokens and refreshes them automatically, so the API key is the only required runtime credential:

export ISLO_API_KEY=islo_key_…

Blaxel: log in to your workspace with the Blaxel CLI (bl login your-workspace), or set the control credentials on the server for a non-interactive process:

export BL_WORKSPACE=your-workspace
export BL_API_KEY=your-api-key

OpenShell: select a gateway with openshell gateway select <name>, or set OPENSHELL_GATEWAY on the server. The launcher uses that gateway connection and does not require a separate API key.

Boxlite: local mode requires KVM on Linux and no provider credential. For a remote boxlite serve pool, set BOXLITE_API_KEY on the server and configure the pool endpoint in the Boxlite settings.

Provider control credentials stay on the launching process and never enter the sandbox. Web users log in to Omnigent, not the sandbox provider.

3. Configure a provider

Add a sandbox section to your server config YAML (~/.omnigent/config.yaml on a laptop, /data/config.yaml in Docker). A typical Modal configuration looks like this:

sandbox:
  provider: modal
  server_url: https://your-server.example.com
  modal:
    image: ghcr.io/omnigent-ai/omnigent-host:latest # optional, official image by default
    secrets: [omnigent-llm] # Modal secrets with LLM API keys

See common settings for the top-level fields, Modal settings for the provider block, and host configuration for host_config. The full cloud sandbox configuration reference also covers the other providers and lifecycle settings.

4. Launch from the web UI

Start a new session and select New Sandbox in the host picker. The server provisions the cloud host, starts the runner, and connects it back automatically.

CLI

Create and manage cloud sandbox hosts from the command line. The commands are the same across CLI-capable providers; switch the --provider flag:

omni sandbox create --provider modal          # or --provider daytona / blaxel / islo / openshell
omni sandbox connect --provider modal \
  --sandbox-id <id> --server <url>

Boxlite supports the server-managed flow but not these CLI bootstrap commands.

For a Blaxel CLI launch, list any credentials the host or agent needs in OMNIGENT_BLAXEL_SANDBOX_ENV before create. Never include BL_API_KEY or BL_CLIENT_CREDENTIALS. Blaxel does not expose local callback port forwarding, so the in-sandbox browser login is skipped automatically.

Stopping connect leaves the sandbox running. Delete it with the provider's CLI or console when you no longer need it.

Reap stale sandboxes (optional)

By default a managed sandbox lives until its session is deleted (or the provider's own lifetime cap reaps it). To automatically terminate sandboxes whose hosts have gone offline and stayed offline, add an optional reaper block to sandbox:. It is deployment-wide — configure it next to provider (or providers:), never inside an individual provider entry:

sandbox:
  provider: modal
  server_url: https://your-server.example.com
  reaper:                              # optional; disabled by default
    enabled: true                      # default: false
    terminate_after_offline_days: 30   # default: 30 days
    sweep_interval_s: 86400            # default: 1 day

Both terminate_after_offline_days and sweep_interval_s must be positive integers. Setting reaper inside a providers: list entry is rejected at startup — one loop covers the whole deployment and dispatches each termination through the provider recorded on the managed host it is reaping.

Reaping detaches only the stale sandbox generation: the session transcript and the durable host binding stay, so the next message to that session can launch a fresh sandbox under the same host identity. A provider termination that fails stays pending and is retried on a later sweep.

The reaper requires a configured host store. If reaper.enabled is true but no host store is configured, the server logs a warning and the reaper does not run.

Community sandbox providers

The providers above ship with Omnigent. Beyond them, the server discovers additional sandbox providers at startup through a plugin registry, so a new hosting platform can be added as a separate package without changing the core omnigent package.

An installed provider behaves like a built-in once it's registered: its name is accepted in the sandbox.provider field, its sandbox.<provider> config block is validated at server startup, and it's offered as a working option in the web UI host picker (managed launch is enabled). If the server config names a provider whose optional package is missing, the server still starts — the failure surfaces on the launch that needs it, naming the provider.

Configure a contributed provider

Set sandbox.provider to the contributed name and, if the provider declares a config model, add a matching sandbox.<provider> block:

sandbox:
  provider: acme
  server_url: https://your-server.example.com
  acme:
    namespace: sandboxes

The block is validated against the provider's declared config model when the server starts, so a typo or a wrong type fails loudly at startup — with the provider named — rather than erroring on the first managed session. A provider that declares no config model takes no block.

Build a provider plugin

A sandbox provider plugin is a Python package that declares an entry point in the omnigent.sandbox_providers group. The entry point resolves to a callable returning a SandboxProviderContribution. Launcher and config-model classes must live under the omnigent.community.sandbox.* namespace.

# pyproject.toml
[project]
name = "omnigent-acme"
dependencies = ["omnigent"]
 
[project.entry-points."omnigent.sandbox_providers"]
acme = "omnigent.community.sandbox.acme.plugin:get_contribution"
# omnigent/community/sandbox/acme/plugin.py
from pydantic import BaseModel
 
from omnigent.onboarding.sandboxes.registry import (
    SandboxProviderContribution,
    SandboxProviderMetadata,
)
 
 
class AcmeConfig(BaseModel):
    namespace: str = "default"
 
 
def get_contribution() -> SandboxProviderContribution:
    return SandboxProviderContribution(
        name="omnigent-acme",
        providers={
            "acme": SandboxProviderMetadata(
                name="acme",
                launcher_class="omnigent.community.sandbox.acme.launcher:AcmeSandboxLauncher",
                config_model=AcmeConfig,       # optional
                managed_token_ttl_s=1234,      # optional; falls back to the Modal TTL
            ),
        },
    )

The launcher subclasses SandboxHostLauncher and, when a config_model is declared, receives the validated config as a config= keyword argument. Providers that declare no model keep a zero-argument constructor. When a provider omits managed_token_ttl_s, its managed-token lifetime falls back to the conservative Modal default.

Note: A plugin can't shadow a built-in provider name, and its launcher class must resolve under the omnigent.community.sandbox.* namespace — the registry rejects it otherwise. A malformed plugin is recorded and skipped rather than crashing server startup.