Skip to content

Support sandbox platforms running on Substrate #553

Description

@ronlv10

Background

One of the potential consumers today with large scale are evaluation and RL frameworks like Harbor and NeMo Gym. These run agents inside execution sandbox environments, and already integrate with several of these platforms: Harbor ships backends for roughly twenty-five providers, e2b and OpenSandbox among them, each implementing a single interface of start, stop, exec, and file upload and download.

Over the last couple of days I looked at what it would take to run a Harbor or NeMo Gym style platform on Substrate. This issue writes up what those platforms need from a compute backend, and the gaps I hit.

What these platforms are

A sandbox platform (like e2b, OpenShell, OpenSandbox) gives an SDK caller a fresh enforced environment: filesystem restrictions, controlled egress, credentials injection. Over that it exposes an API: run a command, stream output, download and upload files, open a shell.

These platforms let users bring their own images, and inject the sandbox binary at execution time without requiring the user's image to be rebuilt. This aligns with Harbor-style systems, which need to run many image types (100+), one per benchmark environment.

A few examples I looked on:

Platform Isolation Source
Vercel Sandbox Firecracker microVM Closed
e2b Firecracker microVM Apache 2.0
NVIDIA OpenShell OCI container Apache 2.0
OpenSandbox (Alibaba) OCI container Apache 2.0

I would focus on the two container-based fully open-sourced platforms, OpenShell and OpenSandbox.

There are certainly more than these, and this list is not meant to be exhaustive. Happy to hear from the community about others worth considering.

Both already support Kubernetes as a pluggable compute backend. Adding Substrate alongside it is the goal this issue is framing.

How they work on Kubernetes

Both follow the same shape: the user brings an arbitrary OCI image, and the platform delivers its own binary into that image at pod-creation time.

OpenShell

A single supervisor binary runs as the container's first process and spawns the agent as a child. Everything the platform enforces lives in that supervisor process: policy decisions, a loopback proxy for egress, credential injection, etc. Because the supervisor owns the child, it applies filesystem and syscall restrictions before the agent ever starts.

Supervisor binary delivery: on modern k8s clusters the supervisor's own OCI image is mounted into the pod as a read-only image volume; on older ones an init container copies the binary into a shared volume. Either way the pod's container command is overridden to point at the delivered binary.

The supervisor container runs as root and is granted capabilities like NET_ADMIN and NET_RAW for network setup, and CHOWN to prepare paths for the sandbox user. The supervisor drops privileges for the child.

The supervisor holds an outbound connection to the control plane and receives exec, file, and policy operations over it.

OpenSandbox

A separate daemon, execd, implements the API surface directly: command execution with streaming output, interactive shell sessions over an ssh-like channel, and file operations. It is delivered by an init container that copies it out of a dedicated image into a shared volume, and the container command is overridden to a bootstrap script that starts execd, then launches the user's workload as a child.

Egress is handled by a second container. A sidecar carrying the network policy joins the pod, holds NET_ADMIN, and installs the rules. The workload container has that same capability explicitly dropped. Since all containers in a pod share one network namespace, the workload's traffic necessarily traverses the sidecar's rules, and the workload has no privilege to inspect or remove them.

The pattern

Reduced to essentials, both need two things from their compute backend:

  1. Deliver a binary into an arbitrary user image and run it as the container process

  2. Give enforcement components privileges the workload does not have

The API for exec, upload and download is not a separate requirement. The injected binary implements it. This is aligned with the comment on #185, which separates exec-into-actor for debugging from the API an execution environment offers, and suggests the latter need not live in Substrate itself.

Gaps identified

1. No way to deliver a binary into an actor

ActorTemplate containers take an image, command, args, env, and volume mounts. Volumes exist, but every source starts empty. Nothing carries content in. The only way to get a binary into an actor today is to have it in the image, which means asking users to rebuild theirs.

2. No per-container capabilities

Every container in an actor receives the same fixed capability set. OpenSandbox's egress model depends on the asymmetry between a privileged sidecar and an unprivileged workload, and OpenShell's supervisor needs elevated privileges to install its controls.

Options to close each gap

Delivering the binary

  • An image volume: a volume source naming an OCI image, mounted read-only into the actor. Something similar to the Kubernetes image volume model.

  • An init container: a phase that runs before the actor's containers, so a user can copy content into a shared volume.

Capabilities

  • Per-container securityContext with capability add on ActorTemplate.

Related work in Substrate

  • #185 exec channel into a running actor

  • #264 an API to push files into an actor

  • #126 transparent egress policy and credential injection

Looking for feedback on the gaps and the options above. Happy to open a separate issue per option we agree on.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions