Pasar al contenido principal
https://catalogartifact.azureedge.net/publicartifacts/lynxroute.openhands-5f54d38a-1cec-4fb1-bc0a-e3d2c276359b/image3_Azureready.png

OpenHands - Hardened Self-Hosted Autonomous AI Agent

por Lynxroute

OpenHands 1.7.0 - CIS Level 1 hardened self-hosted autonomous AI coding agent on Ubuntu 24.04 LTS

What is OpenHands

OpenHands (formerly OpenDevin) is an open-source autonomous AI software engineering agent released under the MIT license. The agent runs inside a sandbox container with read-write access to a workspace, executes shell commands, edits files, and drives a headless browser - controlled from a web IDE that streams live agent events. OpenHands works with any LLM provider via a configurable backend: operators choose the provider in the web UI Settings and paste their API key. No provider keys are baked into the image. Supported integrations include OpenAI-compatible APIs, Anthropic, Azure OpenAI, and local runtimes such as Ollama and vLLM.

Why self-host OpenHands

Self-hosting puts every prompt, every code edit, and every shell command the agent runs entirely inside your own tenant - no third-party visibility into your source, your prompts, or your secrets. Ideal for teams with data residency requirements, organisations operating under HIPAA, GDPR, or ISO 27001, defence and government work, and MSPs that need to keep customer code under their own control.

What this VM image adds

Security hardening:

  • HTTP basic auth gates the agent web UI - Nginx checks credentials before any request reaches OpenHands. Per-instance admin password (Azure vmId UUID) generated at first boot
  • OpenHands bound to 127.0.0.1:3000 - reachable only through the Nginx reverse proxy with TLS, HTTP-to-HTTPS redirect, hardened cipher suite, security headers, and tuning for long-running agent tasks
  • Both Docker images pinned by SHA-256 - openhands main image and the matching agent-server runtime are pre-pulled and pinned by digest in /etc/openhands/openhands.env. Reproducible builds; the first conversation does not block on a multi-gigabyte pull
  • No provider API keys baked in - operators configure their LLM provider through the OpenHands UI Settings after the first login
  • UFW firewall - only TCP 22, 80, and 443 are open
  • fail2ban - SSH brute-force protection
  • AppArmor - mandatory access control
  • CVE scan - every image is scanned with Trivy before release
  • Certbot pre-installed - one command issues a Let's Encrypt certificate after you point a domain at the VM

OS hardening (CIS Level 1):

  • CIS Ubuntu 24.04 LTS Level 1 Benchmark via ansible-lockdown
  • auditd for system call auditing of critical paths
  • SSH hardening - PasswordAuthentication disabled, key-only access
  • Kernel hardening - SYN cookies, ASLR, rp_filter, TCP BBR
  • /tmp as tmpfs with nosuid, nodev, noexec

Compliance artifacts (inside the VM):

  • SBOM - CycloneDX 1.6 at /etc/lynxroute/sbom.json
  • CIS Conformance Report at /etc/lynxroute/cis-report.html
  • Tailored CIS profile at /usr/share/doc/lynxroute/CIS_TAILORED_PROFILE.md
  • Server credentials file - /root/openhands-credentials.txt with the web UI URL, basic auth password, and operator runbook commands

Security model

OpenHands spawns a sandbox container per conversation via /var/run/docker.sock mounted into the agent container. This is required by the upstream design and gives the agent root-equivalent access to the host Docker daemon. Each VM is therefore intended for single-tenant use - do not expose this image to untrusted users. State, settings, and conversation history persist at /opt/openhands/state across container restarts and instance reboots. Agent working files persist at /opt/openhands/workspace - attach a managed disk there for a larger workspace.

Quick Start

  1. Deploy VM from Azure Marketplace (Standard_D2s_v3 or larger, 40 GB OS disk minimum)
  2. Open NSG: TCP 443 from your client networks, TCP 22 from your management IPs only
  3. SSH: ssh -i key.pem azureuser@<PUBLIC_IP>, then sudo cat /root/openhands-credentials.txt for the web UI URL and basic auth password
  4. Open https://<PUBLIC_IP>, accept the self-signed certificate, and authenticate as admin with the password from the credentials file
  5. In the OpenHands UI click Settings -> LLM, choose your provider, and paste your API key
  6. Issue a public TLS certificate before sharing the VM: sudo certbot --nginx -d your.domain.com