kosa8 / Guides

Guide · OpenHands

How do I run OpenHands in a sandbox safely?

Updated

OpenHands runs its agent server in a sandbox chosen with the RUNTIME variable: docker (the default, a Docker container), process (a plain process on your machine, with no container isolation) or remote. For a local install, keep the Docker sandbox, publish the web UI on 127.0.0.1 only and mount only the project folder. The OpenHands app is given the host's Docker socket, so for a stronger boundary run the whole setup inside a separate virtual machine.

01Steps

  1. Install and start OpenHands from the project folder. OpenHands' recommended launcher is a uv tool. --mount-cwd mounts the current directory into the sandbox.

    terminal
    uv tool install openhands --python 3.12
    cd ~/code/app
    openhands serve --mount-cwd
  2. Or run it with Docker and bind to localhost. OpenHands' documented docker run publishes port 3000 on every interface. Its hardening notes (in the legacy V0 docs) say to bind it to 127.0.0.1 instead.

    terminal
    docker run -it --rm --pull=always \
        -e AGENT_SERVER_IMAGE_REPOSITORY=ghcr.io/openhands/agent-server \
        -e AGENT_SERVER_IMAGE_TAG=1.26.0-python \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v ~/.openhands:/.openhands \
        -p 127.0.0.1:3000:3000 \
        --add-host host.docker.internal:host-gateway \
        --name openhands-app \
        docker.openhands.dev/openhands/openhands:1.8
  3. Mount only the project. SANDBOX_VOLUMES takes host_path:container_path[:mode]. OpenHands warns that anything mounted read-write into /workspace can be modified by the agent. The V0 docs document ro for reference code.

    terminal
    export SANDBOX_VOLUMES=$PWD:/workspace:rw
  4. Keep the Docker sandbox. Leave RUNTIME unset or set to docker. OpenHands labels the process sandbox “unsafe, but fast”; keep it for a throwaway machine or CI runner.

    terminal
    export RUNTIME=docker
  5. Avoid host networking unless you need it. AGENT_SERVER_USE_HOST_NETWORK=true puts sandboxes on the host network and exposes ports 8000, 8001, 8011 and 8012 on the host. Leave it unset.

  6. Run the Docker host itself in a VM. Give OpenHands a Docker engine inside a dedicated virtual machine (for example in UTM or Lima), with only the project folder shared. The socket it holds then controls that VM's engine, not your workstation's.

02What sandbox runtimes does OpenHands support?

Current OpenHands docs list three sandbox providers: Docker, which runs the agent server in a container and is the default; Process, which runs it as a regular process with no container isolation; and Remote, used by managed and some hosted deployments. You choose with RUNTIME=docker, RUNTIME=process (formerly local) or RUNTIME=remote.

The docs say the user-facing name changed from runtime to sandbox in V1, while the setting may still be called RUNTIME during the migration. The legacy V0 docs describe the same three as Docker Runtime, Local Runtime and Remote Runtime.

03Is the OpenHands Docker runtime secure?

It isolates the agent's commands in a container, which reduces risk, but the OpenHands app container is started with the host's Docker socket mounted. Docker's security documentation says only trusted users should control the Docker daemon, because it can share any host directory with a container.

Containers also share the host kernel. OpenHands' V0 docs add that nothing stops the agent from deleting or modifying files mounted into its workspace, and recommend binding the UI to 127.0.0.1 and using an isolated Docker network where security is a priority.

04Can OpenHands use a microVM sandbox such as kosa8?

Not as a documented integration. kosa8 has a Docker-compatible API that has been tested with Testcontainers, dockerode, smolagents and the OpenAI Agents SDK, but not with OpenHands.

kosa8 also refuses, on purpose, to mount its Docker API socket into a container, because a container holding the socket controls every other container. OpenHands' documented docker run command mounts that socket, so pointing it at kosa8 with DOCKER_HOST should not be expected to work as it stands. Until it is tested, the dependable way to put a VM boundary around OpenHands is to run the Docker host inside a VM, as in the last step.

05Other options

  • OpenHands' Remote sandbox. Moves execution off your machine; fits managed and hosted deployments.
  • Docker with gVisor or Kata Containers. Docker can use either as its container runtime for a stronger boundary than a shared kernel. OpenHands' docs do not cover running under them, so test before relying on it.
  • A full VM in UTM or Lima. Runs Docker and OpenHands together on a separate machine, with one shared folder.
  • Cloud sandboxes such as E2B, Daytona or Modal. Fit agent code you write yourself, rather than OpenHands' own sandbox.

06Sources