DEV Community

jamilxt
jamilxt

Posted on

OpenHands at 1.x: How to Run It on Your Own Machine Without Handing Over the Keys

Last December, OpenHands, the open-source autonomous coding agent, hit its 1.0 release: production-ready Docker sandboxing, built-in security policies, resource limits, and a plugin system. It shipped on top of a ground-up rewrite called the Software Agent SDK, and the project has kept a steady release cadence since. This guide is about the version that exists now, what the 1.x architecture actually gives you, and how to run it on your own machine without handing over the keys.

The 1.x releases matter if you care about where your code and your API keys live. The open option is no longer a hobby project trailing the commercial agents. OpenHands holds leaderboard entries above 70% on SWE-bench Verified with a frontier model, which puts it in the same conversation as commercial agents that cost real money per task, and the stack ships the safety rails that used to be the excuse for not self-hosting.

I run my own AI agent infrastructure that publishes articles and manages my content pipeline overnight, so this is a topic I care about personally. Full disclosure before we go further: an earlier version of this article framed the 1.0 release as fresh news, which it was not. OpenHands 1.0.0 shipped on December 16, 2025, and an OpenHands team member kindly pointed out the error. I have rewritten the piece against the current docs and release history. Everything below now comes from the official documentation, the SDK paper, and published benchmark data, with my own judgment layered on top.

Here is the setup and lockdown guide I wish had existed when I first went looking.

What 1.0 Actually Changed

OpenHands 1.0 was not a feature bump. It was a ground-up rebuild around a Software Agent SDK, documented in a paper the team published on arXiv. The old version was a monolith where agent logic, evaluation, and the web app all lived in one codebase. The new version splits into four Python packages with sharp boundaries:

  • openhands.sdk holds the core abstractions: Agent, Conversation, LLM, Tool, and the event system.
  • openhands.tools provides concrete tool implementations built on those abstractions.
  • openhands.workspace manages execution environments, including the Docker sandbox.
  • openhands.agent_server exposes REST and WebSocket APIs for remote execution.

Three design choices in the new architecture matter to you as an operator:

Everything is an event. Every prompt, bash command, file change, and compiler error is an immutable event in an append-only log. This gives you deterministic replay and session recovery. When an agent does something weird at 3 AM, you can replay exactly what happened instead of guessing from a chat transcript.

Components are immutable. Agents, tools, and LLM configs are validated Pydantic models frozen at construction. The only mutable thing is the conversation state. This sounds academic until you have debugged an agent whose config silently drifted mid-run.

Security is a first-class loop, not a checkbox. A SecurityAnalyzer rates every tool call as low, medium, or high risk. A ConfirmationPolicy decides whether the agent must pause and wait for your approval before executing. With the ConfirmRisky policy, the agent sits in a WAITING_FOR_CONFIRMATION state until a human says yes. That is the exact mechanism the agent-safety people have been asking for, and it is on by default in the stack.

On capability: OpenHands' best official SWE-bench Verified submission resolves 71.8% of the 500 real GitHub issues. For context, Devin 2.0 publicly reported around 45.8%. OpenHands paired with Devstral 24B, an open-weight model, scores roughly 46.8%, which already matches Devin's commercial number.

Install in Ten Minutes

A correction from the earlier version of this post: the uv tool install openhands CLI and the install-script binary come from the OpenHands CLI repo, which the team has now marked as no longer actively maintained. Their current recommendation is Agent Canvas, the self-hosted control center that ships in the main OpenHands repo. Use that instead:

npm install -g @openhands/agent-canvas
agent-canvas
Enter fullscreen mode Exit fullscreen mode

Prerequisites are Node.js and uv, which the local agent server runtime uses. The docs list Node 22.12 or later; the current published package asks for Node 24 or newer, so install the newest LTS and you are covered either way. Agent Canvas starts a full local stack and serves the UI at http://localhost:8000. If you prefer containers, the Docker path is:

mkdir -p ~/projects ~/.openhands

docker run -it --rm \
  -p 8000:8000 \
  -v ~/.openhands:/home/openhands/.openhands \
  -v ~/projects:/projects \
  ghcr.io/openhands/agent-canvas:latest
Enter fullscreen mode Exit fullscreen mode

The first run walks you through LLM configuration in Settings. Open a workspace folder before starting a conversation if you want the agent confined to a specific project. That gets the agent running. Do not stop here. Running an autonomous coding agent directly on your workstation with full access is exactly the configuration you should avoid, for reasons I will come back to.

The Docker Path: Isolation as the Default

The earlier version of this post carried a Docker launch command from the deprecated CLI era. That setup is gone from the current docs. The isolation story now lives in the SDK's DockerWorkspace and in Agent Canvas's Docker mode, and the principle is the same one the old docs stated: isolation reduces the risk when the agent runs commands, and it makes the environment reproducible across machines.

With Agent Canvas, the containerized path is the ghcr.io/openhands/agent-canvas image from the install section above. The agent can only reach files under the mounted /projects directory, which is your boundary. The docs are explicit that the Canvas client itself provides no isolation; the container is the isolation. If you skip the container, the agent acts with your user account's permissions on your host.

For programmatic use, the Software Agent SDK gives you DockerWorkspace, which manages the container lifecycle for you:

from openhands.workspace import DockerWorkspace

with DockerWorkspace(
    server_image="ghcr.io/openhands/agent-server:latest-python",
    host_port=8010,
) as workspace:
    conversation = Conversation(agent=agent, workspace=workspace)
Enter fullscreen mode Exit fullscreen mode

The workspace pulls the pre-built agent-server image, starts the container, waits for the server to be ready, and tears it all down when the context exits. Switching a local conversation to a sandboxed one is a one-line change: swap workspace=os.getcwd() for a DockerWorkspace instance. The docs also offer DockerDevWorkspace for building custom images on the fly, and an APIRemoteWorkspace that points at hosted infrastructure instead.

Two rules carry over unchanged from the old setup, because they were always about the mount, not the launcher:

  • Mount only the project you are working on. Anything mounted read-write into the container is fair game for the agent. This is the single most important knob in the whole setup. Mount your home directory and you have handed an LLM a paintbrush for your entire machine. Mount one project folder and the blast radius of a bad decision is one folder.
  • Treat the container as the security boundary, not the UI. The docs say it plainly: agents and agent processes are untrusted. They can run shell commands, read files, write files, and use connected tools within their execution environment. The container defines how far that reaches.

The Lockdown Checklist

Here is the save-worthy part. Self-hosting an autonomous agent is only responsible if you actually constrain it. Work through this list before your first real task:

  • Enable the confirmation policy. The SDK ships a ConfirmRisky policy that pairs with the LLM security analyzer. High-risk tool calls, think destructive bash commands or anything touching credentials, pause the agent until you approve. You trade a little latency for not discovering deletions after the fact.
  • Cut the network when you can. The old CLI exposed a SANDBOX_NETWORK_DISABLED env var; in the current stack, network limits are a property of the sandbox you build. A container with no bridge network and no egress rule cannot exfiltrate your secrets or download surprises. Yes, this breaks tasks that need to pip install or hit APIs. For refactoring, test writing, and code review tasks, the agent does not need the internet anyway.
  • Harden the container itself. Run sandbox containers with --security-opt no-new-privileges and --read-only where your workflow allows. These are standard Docker flags, but they matter more here because the container's purpose is to run commands an LLM chose.
  • Mount secrets read-only, or not at all. Pass credentials through environment variables referenced from a read-only secrets directory. Never bake them into the workspace the agent edits. The SDK has secrets auto-masking built in; meet it halfway by not putting secrets in writable paths.
  • Review the event log after every session. The 1.x architecture is event-sourced: every prompt, command, and file change is an immutable entry. Walking the log after early sessions costs nothing and teaches you the agent's decision patterns before you give it real work.
  • Know the limits of the security analyzer. The SDK paper's own limitations section flags that the LLM-based risk classifier is probabilistic, not a guarantee. Treat it as a helpful reviewer with good instincts, not a firewall.

One honest gap: the 1.0 core focuses on single-agent conversations. Delegation exists as a blocking parallel tool, but rich multi-agent orchestration is explicitly future work. If your use case is a swarm of cooperating agents, the commercial tools are further along today. If your use case is one capable agent doing real repo work safely on your own hardware, this is your release.

The Economics: Why Self-Hosting the Agent Tier Is Now Real

The cost math is the quiet story here. Commercial autonomous agents charge per task on subscription models. A self-hosted OpenHands stack costs roughly $0.20 to $1.05 per resolved task at H100 GPU rates, depending on which model you put behind it, based on published community analysis. That is the agent harness cost. Your model API bill sits on top if you use hosted models, or disappears entirely if you run open-weight models like Devstral on your own GPUs.

And the open-weight path is no longer embarrassing. OpenHands with Devstral 24B at 46.8% on SWE-bench Verified matches what Devin 2.0, a funded commercial product, publicly reported. For internal tooling, dependency upgrades, boilerplate features, and test coverage work, an open model through an open harness at a fraction of the cost is a legitimate production choice in September 2026. For your hardest architectural work, put the frontier model behind the same harness. The harness does not care.

How I Would Roll It Out

If I were adopting this on my own infrastructure this week, my sequence would be:

  • Week 1: Install Agent Canvas, wire it to my existing model API key, and use it only on a throwaway repository. Read the event log after every session until the agent's decision patterns feel familiar.
  • Week 2: Move to the Docker sandbox with mounts locked to single project folders, ConfirmRisky enabled, and network access removed for tasks that do not need downloads.
  • Week 3: Trial it on a real but low-stakes backlog: dependency bumps, test coverage, doc generation. Compare resolved-task quality and cost against the commercial agent I would otherwise pay for.

I write about AI agents, developer tools, and building with AI every week. Subscribe, it's free, and the next piece in this series will cover wiring OpenHands to open-weight models end to end.

What about you? Have you run OpenHands or another self-hosted coding agent on your own hardware? Did the sandbox hold up, or did you catch it doing something you did not authorize? Tell me in the comments, I read every one.

Sources

Top comments (0)