# How to Implement a Custom Runtime for OpenSandbox: A 5-Step Technical Guide

> Learn how to implement a custom runtime for OpenSandbox in 5 clear steps. Extend RuntimeConfig, create a SandboxService subclass, implement lifecycle methods, and register your runtime.

- Repository: [Alibaba/OpenSandbox](https://github.com/alibaba/OpenSandbox)
- Tags: how-to-guide
- Published: 2026-03-08

---

**To implement a custom runtime for OpenSandbox, extend the `RuntimeConfig` type enumeration, create a concrete class inheriting from `SandboxService`, implement the required lifecycle methods (`create_sandbox`, `delete_sandbox`, `pause_sandbox`, `resume_sandbox`), and register the runtime-to-class mapping in the service factory.**

OpenSandbox is an open-source sandbox platform developed by Alibaba that abstracts container runtimes behind a unified API. When you need to integrate a proprietary orchestrator or an unsupported container engine, you must implement a custom runtime for OpenSandbox to handle sandbox lifecycle operations according to the `SandboxService` contract. This guide walks through the exact source code locations and implementation patterns required to extend the pluggable runtime layer without modifying client SDKs.

## Step 1: Extend the Runtime Configuration in [`config.py`](https://github.com/alibaba/OpenSandbox/blob/main/config.py)

The server determines which runtime to instantiate based on the `type` field in `RuntimeConfig`. To add a new runtime option, modify the Literal type definition in [`server/src/config.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/config.py).

Locate the `RuntimeConfig` class (lines 307-321) and add your runtime identifier to the `type` field:

```python

# server/src/config.py

from typing import Literal
from pydantic import BaseModel, Field

class RuntimeConfig(BaseModel):
    """Runtime selection (docker, kubernetes, etc.)."""
    type: Literal["docker", "kubernetes", "mycustom"] = Field(
        ...,
        description="Active sandbox runtime implementation."
    )
    execd_image: str = Field(
        ...,
        description="Container image that contains the execd binary for sandbox initialization.",
    )

```

If your runtime supports secure sandboxing, also update `SecureRuntimeConfig` (lines 321-330) to include the new type in its Literal definition.

## Step 2: Implement the `SandboxService` Interface

Create a new file in `server/src/services/` (for example, [`mycustom.py`](https://github.com/alibaba/OpenSandbox/blob/main/mycustom.py)) that inherits from the abstract `SandboxService` base class defined in [`server/src/services/sandbox_service.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/sandbox_service.py). This class acts as the runtime contract that OpenSandbox uses to manage sandbox lifecycles.

### Required Lifecycle Methods

Your concrete implementation must override these abstract methods:

- **`create_sandbox`** – Provision the sandbox in your platform, inject the `execd` daemon, and return a `SandboxStatus` object
- **`delete_sandbox`** – Clean up resources and terminate the sandbox
- **`pause_sandbox`** – Suspend execution (optional depending on platform capabilities)
- **`resume_sandbox`** – Resume execution from paused state

```python

# server/src/services/mycustom.py

from src.services.sandbox_service import SandboxService
from src.models import CreateSandboxRequest, SandboxStatus

class MyCustomRuntimeService(SandboxService):
    """Concrete runtime that talks to MyCustom orchestrator."""

    async def create_sandbox(self, req: CreateSandboxRequest) -> SandboxStatus:
        # 1. Provision the sandbox in MyCustom platform

        sandbox_id = await mycustom_client.create_sandbox(
            image=req.image.uri,
            entrypoint=req.entrypoint,
            resources=req.resourceLimits,
        )
        # 2. Inject execd binary (same process as Docker/K8s)

        await mycustom_client.inject_execd(sandbox_id, req.execd_image)
        # 3. Return initial status

        return SandboxStatus(
            id=sandbox_id,
            state="Pending",
            reason="Provisioning",
            message="Sandbox is being prepared."
        )

    async def delete_sandbox(self, sandbox_id: str) -> None:
        await mycustom_client.delete_sandbox(sandbox_id)

    async def pause_sandbox(self, sandbox_id: str) -> None:
        await mycustom_client.pause_sandbox(sandbox_id)

    async def resume_sandbox(self, sandbox_id: str) -> None:
        await mycustom_client.resume_sandbox(sandbox_id)

```

### Execd Injection Requirement

The **execd** daemon is mandatory for OpenSandbox's command execution protocol. Your `create_sandbox` implementation must inject the execd binary (specified by `req.execd_image`) into the sandbox environment, mirroring the approach used in the reference Docker and Kubernetes implementations.

## Step 3: Register Your Runtime in the Service Factory

OpenSandbox uses a factory pattern to instantiate the correct runtime service. Add your runtime-to-class mapping in [`server/src/services/factory.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/factory.py) within the `SERVICE_MAP` dictionary (lines 55-62):

```python

# server/src/services/factory.py

from src.services.mycustom import MyCustomRuntimeService
from src.services.docker import DockerSandboxService
from src.services.k8s.kubernetes_service import KubernetesSandboxService

SERVICE_MAP: dict[str, type[SandboxService]] = {
    "docker": DockerSandboxService,
    "kubernetes": KubernetesSandboxService,
    # Register the new runtime here

    "mycustom": MyCustomRuntimeService,
}

```

When the server configuration specifies `runtime.type: mycustom`, the factory instantiates `MyCustomRuntimeService` to handle all sandbox operations.

## Step 4: Configure Secure Runtime Mappings (Optional)

If your custom runtime requires a specific OCI runtime (for Docker) or Kubernetes `RuntimeClass`, extend the `SecureRuntimeResolver` in [`server/src/services/runtime_resolver.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/runtime_resolver.py). This resolver translates high-level secure runtime names into backend-specific flags.

Update the default mapping tables to include your runtime:

```python

# server/src/services/runtime_resolver.py

class SecureRuntimeResolver:
    DEFAULT_DOCKER_RUNTIMES = {
        "gvisor": "runsc",
        "kata": "kata-runtime",
        # Add custom mapping

        "mysecure": "mycustom-runtime",
    }
    DEFAULT_K8S_RUNTIME_CLASSES = {
        "gvisor": "gvisor",
        "kata": "kata-qemu",
        "firecracker": "kata-fc",
        # Custom class example

        "mysecure": "mycustom-runtimeclass",
    }

```

## Step 5: Document and Test Your Implementation

Update the architecture documentation at [`docs/architecture.md`](https://github.com/alibaba/OpenSandbox/blob/main/docs/architecture.md) in the **Custom Runtime** section to describe your runtime's specific behaviors and requirements. Write integration tests under `tests/python/` that verify:

1. Sandbox creation returns correct `SandboxStatus`
2. Lifecycle transitions (pause/resume) propagate correctly
3. Resource cleanup occurs on `delete_sandbox`
4. Execd injection succeeds and the daemon responds to the OpenAPI spec ([`specs/execd-api.yaml`](https://github.com/alibaba/OpenSandbox/blob/main/specs/execd-api.yaml))

## How the Pluggable Runtime Architecture Works

OpenSandbox follows a **protocol-first, plug-in-first** design that decouples the API layer from runtime implementations. The server only recognizes an abstract **runtime type** string and delegates all concrete operations to the registered `SandboxService` implementation.

This architecture relies on three core contracts:

- **OpenAPI Specifications** ([`specs/execd-api.yaml`](https://github.com/alibaba/OpenSandbox/blob/main/specs/execd-api.yaml), [`specs/sandbox-lifecycle.yml`](https://github.com/alibaba/OpenSandbox/blob/main/specs/sandbox-lifecycle.yml)) define the external interaction protocols
- **SandboxService Interface** ([`server/src/services/sandbox_service.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/sandbox_service.py)) establishes the internal contract for lifecycle operations
- **Service Factory** ([`server/src/services/factory.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/factory.py)) provides runtime selection without code changes to the API server or client SDKs

Because client libraries in `sdks/sandbox/python` communicate through the REST API and lifecycle events, they automatically support any registered runtime without modification.

## Summary

- **Extend `RuntimeConfig`** in [`server/src/config.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/config.py) to add your runtime type to the allowed Literal values
- **Implement `SandboxService`** in a new file under `server/src/services/`, ensuring you handle execd injection and the four required lifecycle methods
- **Register the mapping** in [`server/src/services/factory.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/factory.py) to link the configuration type string to your concrete class
- **Configure secure runtimes** in [`server/src/services/runtime_resolver.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/runtime_resolver.py) if using custom OCI runtimes or Kubernetes RuntimeClasses
- **Reference existing implementations** in [`server/src/services/docker.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/docker.py) and [`server/src/services/k8s/kubernetes_service.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/k8s/kubernetes_service.py) for patterns on execd injection and resource management

## Frequently Asked Questions

### What methods must I implement in SandboxService?

You must implement `create_sandbox`, `delete_sandbox`, `pause_sandbox`, and `resume_sandbox`. The `create_sandbox` method must provision resources in your platform, inject the execd daemon using the provided `execd_image`, and return a `SandboxStatus` object tracking the sandbox state. These methods are defined as abstract in [`server/src/services/sandbox_service.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/sandbox_service.py).

### Do client SDKs require updates for new runtimes?

No. Client SDKs in `sdks/sandbox/python` communicate through the OpenSandbox REST API and do not interact directly with runtime implementations. Once you register your runtime in the factory and configure the server to use it via `runtime.type`, existing SDKs automatically work with your custom runtime without code changes.

### How does the execd daemon injection work in custom runtimes?

Your `create_sandbox` implementation must pull the container image specified by `req.execd_image` and inject the binary into the sandbox environment. This typically involves copying the execd binary into a shared volume or sidecar container, then starting the daemon process. Refer to the Docker and Kubernetes implementations in [`server/src/services/docker.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/docker.py) for specific injection patterns using the `execd_image` configuration field.

### Where can I find reference implementations?

Study [`server/src/services/docker.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/docker.py) for container-based runtimes and [`server/src/services/k8s/kubernetes_service.py`](https://github.com/alibaba/OpenSandbox/blob/main/server/src/services/k8s/kubernetes_service.py) for orchestrator-based implementations. Both demonstrate how to handle the `CreateSandboxRequest` model, manage resource limits, and report state transitions through the Lifecycle API defined in [`specs/sandbox-lifecycle.yml`](https://github.com/alibaba/OpenSandbox/blob/main/specs/sandbox-lifecycle.yml).