> ## Documentation Index
> Fetch the complete documentation index at: https://allhandsai-docs-path-based-sandbox-routing-v2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quick Start

> Get started with a 30-day trial of OpenHands Enterprise.

This guide walks you through trialing OpenHands Enterprise on your own infrastructure.
You'll provision infrastructure (AWS Terraform or a manual VM setup), configure
GitHub for user authentication, and set up Anthropic as your LLM provider.

## Who This Is For

This guide is **not** for single-user local laptop installs. It is for a **30-day trial of OpenHands Enterprise** on a
**dedicated VM/server** on your own infrastructure. The deployment requires DNS records, network, and compute setup before installation.

If you want to use OpenHands immediately without infrastructure setup:

* Use OpenHands Cloud (SaaS)
* Run OpenHands open-source locally using Docker, CLI or SDK

### Accounts and Credentials

Before you begin, make sure you have the following ready:

* **Anthropic API key** from the [Anthropic Console](https://console.anthropic.com/)
* **A GitHub account** with permission to create GitHub Apps
* **An AWS account** with permissions to create EC2, VPC, and Route53 resources (**if using the AWS with Terraform path**)

## Provision Infrastructure

You will need a VM to host OpenHands Enterprise. Choose one of the options below to provision your infrastructure.

<Tabs>
  <Tab title="AWS with Terraform (Recommended)">
    We provide a [Terraform module](https://github.com/All-Hands-AI/OpenHands-Cloud/tree/main/terraform/aws) that provisions a properly configured environment
    for OpenHands Enterprise, including the EC2 instance, DNS records, and TLS certificates.

    <Card title="OpenHands AWS Terraform Module" icon="github" href="https://github.com/All-Hands-AI/OpenHands-Cloud/tree/main/terraform/aws">
      Follow the README instructions to configure and apply the Terraform configuration.
    </Card>
  </Tab>

  <Tab title="Manual VM Setup">
    If you are provisioning a VM manually (on-premises or on another cloud provider),
    it must meet the requirements below.

    <Accordion title="System requirements">
      | Resource                   | Requirement                 |
      | -------------------------- | --------------------------- |
      | **vCPUs**                  | 16                          |
      | **Memory**                 | 64 GB                       |
      | **Disk**                   | 200 GB                      |
      | **Disk P99 write latency** | 10 ms maximum               |
      | **OS**                     | Linux (x86-64 architecture) |
      | **Init system**            | systemd                     |
      | **Access**                 | Root access (sudo) required |
    </Accordion>

    <Accordion title="Network requirements">
      **Firewall inbound rules** -- the following ports must be open:

      | Port  | Protocol | Purpose               |
      | ----- | -------- | --------------------- |
      | 80    | TCP      | HTTP ingress/redirect |
      | 443   | TCP      | HTTPS                 |
      | 30000 | TCP      | Admin Console         |

      **Local ports** -- the following ports must be available for local processes (no firewall rules needed):

      `2379/TCP`, `7443/TCP`, `9099/TCP`, `10248/TCP`, `10257/TCP`, `10259/TCP`

      **Outbound access** -- the VM must be able to reach:

      * `replicated.app`
      * `proxy.replicated.com`
      * `images.r9.all-hands.dev`
      * `install.r9.all-hands.dev`
      * `charts.r9.all-hands.dev`
      * `updates.r9.all-hands.dev`
      * `github.com`
      * `traefik.github.io`
      * `registry-1.docker.io`
      * `ghcr.io`
    </Accordion>

    <Accordion title="System directories created by the installer">
      The installation creates directories and files in the following locations:

      ```
      /etc/cni
      /etc/k0s
      /opt/cni
      /opt/containerd
      /run/calico
      /run/containerd
      /run/k0s
      /sys/fs/cgroup/kubepods
      /sys/fs/cgroup/system.slice/containerd.service
      /sys/fs/cgroup/system.slice/k0scontroller.service
      /usr/libexec/k0s
      /usr/local/bin/k0s
      /var/lib/calico
      /var/lib/cni
      /var/lib/containers
      /var/lib/embedded-cluster
      /var/lib/kubelet
      /var/log/calico
      /var/log/containers
      /var/log/embedded-cluster
      /var/log/pods
      ```
    </Accordion>

    ### DNS and TLS Setup

    Once your VM is running, configure DNS and TLS before starting the installer.

    OpenHands supports two routing modes for sandbox (runtime) URLs. Choose the mode that
    fits your infrastructure requirements:

    <Warning>
      **Security Recommendation: Use Subdomain Routing When Possible**

      While many corporate IT security departments prefer to avoid wildcard certificates as a
      general policy, **subdomain-based routing provides superior security isolation** for OpenHands.

      With subdomain routing, cookies issued by applications running in sandbox environments are
      scoped to that specific sandbox's domain (e.g., `abc123.runtime.example.com`). This prevents
      one sandbox from accessing cookies issued by another sandbox — an important security boundary
      when running untrusted or user-provided code.

      Path-based routing shares a single domain across all sandboxes, which reduces this isolation.

      **We encourage customers to request an exception from corporate IT security** by explaining
      this security benefit. Use subdomain routing wherever possible.
    </Warning>

    <Tabs>
      <Tab title="Subdomain Mode (Default)">
        In subdomain mode, each sandbox is accessible at its own subdomain (e.g., `{sandbox_id}.runtime.example.com`).
        This is the default and recommended mode for most deployments.

        **Create DNS A records** pointing to your VM's public IP address:

        | Record                      | Example                             |
        | --------------------------- | ----------------------------------- |
        | `<your-domain>`             | `openhands.example.com`             |
        | `app.<your-domain>`         | `app.openhands.example.com`         |
        | `auth.app.<your-domain>`    | `auth.app.openhands.example.com`    |
        | `llm-proxy.<your-domain>`   | `llm-proxy.openhands.example.com`   |
        | `runtime-api.<your-domain>` | `runtime-api.openhands.example.com` |
        | `*.runtime.<your-domain>`   | `*.runtime.openhands.example.com`   |

        **Obtain a TLS certificate** with SANs (Subject Alternative Names) for all of the above domains,
        including the **wildcard** `*.runtime.<your-domain>`.
      </Tab>

      <Tab title="Path-Based Mode">
        In path-based mode, all sandboxes share a single hostname with different path prefixes
        (e.g., `runtime.example.com/{sandbox_id}`). Use this mode when:

        * Your certificate authority does not issue wildcard certificates
        * Compliance requirements prohibit wildcard certificates
        * Wildcard DNS records are not supported in your environment

        **Create DNS A records** pointing to your VM's public IP address:

        | Record                      | Example                             |
        | --------------------------- | ----------------------------------- |
        | `<your-domain>`             | `openhands.example.com`             |
        | `app.<your-domain>`         | `app.openhands.example.com`         |
        | `auth.app.<your-domain>`    | `auth.app.openhands.example.com`    |
        | `llm-proxy.<your-domain>`   | `llm-proxy.openhands.example.com`   |
        | `runtime-api.<your-domain>` | `runtime-api.openhands.example.com` |
        | `runtime.<your-domain>`     | `runtime.openhands.example.com`     |

        **Note:** No wildcard DNS record is required. The `runtime.<your-domain>` record replaces `*.runtime.<your-domain>`.

        **Obtain a TLS certificate** with SANs for the above domains. **No wildcard SAN is required** —
        only the base `runtime.<your-domain>` hostname.

        <Info>
          You will configure **path-based routing mode** in the Admin Console under **Sandbox Configuration**
          after installation. See [Sandbox Routing Configuration](#sandbox-routing-configuration) below.
        </Info>
      </Tab>
    </Tabs>

    **Certificate requirements:** Copy your TLS certificate (`.pem` or `.crt`) and private key
    (`.pem` or `.key`) to the VM. Both CA-signed certificates (e.g., from Let's Encrypt) and
    self-signed certificates are supported.

    <Warning>
      If you don't provide TLS certificates during installation, the Admin Console will use a
      self-signed certificate and your browser will display a security warning. You can still
      upload your certificate afterward through the Admin Console.
    </Warning>
  </Tab>
</Tabs>

## Preflight Validation

All items below must be completed before running the installer:

* VM meets CPU, memory, disk, and OS requirements
* DNS records are created and resolve from the VM
* Inbound ports are open: `80`, `443`, and `30000`
* Outbound domains are reachable from the VM
* GitHub App prerequisites are prepared

<Warning>
  Do not run the installer until preflight checks pass.
</Warning>

### DNS checks

Run the checks below on the target VM before opening the installer dashboard.

Export your base domain:

```bash theme={null}
export BASE_DOMAIN="openhands.example.com"
```

Test DNS:

```bash theme={null}
for h in \
  "${BASE_DOMAIN}" \
  "app.${BASE_DOMAIN}" \
  "auth.app.${BASE_DOMAIN}" \
  "llm-proxy.${BASE_DOMAIN}" \
  "runtime-api.${BASE_DOMAIN}"; do
  echo "[DNS] $h"
  getent hosts "$h" || nslookup "$h"
done
```

Expected: each hostname above resolves to your VM's public IP address.

**For subdomain routing mode (default):** Test that a runtime wildcard hostname resolves:

```bash theme={null}
getent hosts "test.runtime.${BASE_DOMAIN}" || nslookup "test.runtime.${BASE_DOMAIN}"
```

Expected: `test.runtime.${BASE_DOMAIN}` resolves to the same target as `${BASE_DOMAIN}`.

**For path-based routing mode:** Test that the runtime base hostname resolves:

```bash theme={null}
getent hosts "runtime.${BASE_DOMAIN}" || nslookup "runtime.${BASE_DOMAIN}"
```

Expected: `runtime.${BASE_DOMAIN}` resolves to the same target as `${BASE_DOMAIN}`.

### Outbound connectivity checks

```bash theme={null}
urls=(
  "https://replicated.app"
  "https://proxy.replicated.com/v2/"
  "https://images.r9.all-hands.dev/v2/"
  "https://install.r9.all-hands.dev"
  "https://charts.r9.all-hands.dev"
  "https://updates.r9.all-hands.dev"
  "https://github.com"
  "https://traefik.github.io/charts/index.yaml"
  "https://registry-1.docker.io/v2/"
  "https://ghcr.io/v2/"
)

for u in "${urls[@]}"; do
  # HTTP 000 means connection failure (DNS failure, timeout, or blocked network path).
  code=$(curl -sSIL --max-time 15 -o /dev/null -w "%{http_code}" "$u" || true)
  if [ "$code" = "000" ]; then
    echo "FAIL $u"
  else
    echo "OK   $u (HTTP $code)"
  fi
done
```

Any HTTP response code other than `000` is acceptable for reachability checks
(for example `200`, `301`, `302`, `401`, `403`, `405`).

If any check fails, stop and resolve before continuing:

* DNS failures: Verify records are created, point to the right target, and have finished propagating
* Outbound connectivity failures: Check firewall egress rules, proxy settings, and TLS inspection policies

## Reasons for Requirements

| Requirement                                                      | Why It Exists                                                                                  |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `443/TCP` inbound                                                | Primary HTTPS entrypoint for users and service hostnames                                       |
| `30000/TCP` inbound                                              | Replicated/KOTS Admin Console for install and configuration                                    |
| `80/TCP` inbound                                                 | HTTP entrypoint used for ingress/redirect behavior                                             |
| `*.runtime.<domain>` DNS + cert SAN                              | **Subdomain mode only**: Runtime sandboxes are addressed by dynamic runtime-specific hostnames |
| `runtime.<domain>` DNS + cert SAN                                | **Path-based mode only**: Runtime base hostname for path-based sandbox routing                 |
| `replicated.app`, `proxy.replicated.com`                         | Replicated control-plane/license/install paths                                                 |
| `images.r9...`, `charts.r9...`, `updates.r9...`, `install.r9...` | Vendor distribution image/chart/update/install endpoints                                       |
| `traefik.github.io`                                              | Embedded cluster ingress chart repository                                                      |
| `ghcr.io`, `registry-1.docker.io`                                | Container image pulls for platform components                                                  |
| `github.com`                                                     | GitHub App setup/auth/webhooks and downloading public agent skills                             |

## Run the Installer

### 1. Access the Installer Dashboard

After preflight validation checks have passed, [register for a free 30-day trial](https://install.r9.all-hands.dev/openhands/signup), then
log in to the installer dashboard. You will see the dashboard below.
Click **"View install guide"** in the Install tile.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/admin-dashboard.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=0def30638d55d5cbbec6fdc713e90f70" alt="Installer Dashboard" width="1277" height="1214" data-path="enterprise/images/admin-dashboard.png" />

### 2. Name your instance

Enter a name for your instance (e.g., your company name or environment identifier).
Select **"Outbound requests allowed"** for Network Availability, then click **Continue**.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/install-instance-name.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=00bd3b03744cb6aaa7fbe86591ccdda1" alt="Instance name and network availability" width="1277" height="1214" data-path="enterprise/images/install-instance-name.png" />

### 3. Run the installation commands

The install guide provides commands to run on your VM. SSH into your VM and execute them in order:

1. **Select a version** -- the latest version is pre-selected
2. **Download the installation assets** -- copy and run the `curl` command shown
3. **Extract the installation assets** -- run the `tar` command shown (this includes your license file)
4. **Install** -- run the install command shown

If the install command fails after preflight checks pass, run `sudo ./openhands support-bundle` and share the resulting bundle with support.

<Warning>
  **We recommend providing your TLS certificates during installation.** If you used the
  Terraform module, the certificates are in your home directory:

  ```bash theme={null}
  sudo ./openhands install --license license.yaml \
    --tls-cert ~/certificate.pem \
    --tls-key ~/private-key.pem
  ```

  If you provisioned manually and have your own certificates on the VM, pass them the same way.
  You can also omit the `--tls-cert` and `--tls-key` flags and upload certificates later through
  the Admin Console.
</Warning>

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/install-commands.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=8de74d1f8a724c847f259636cd8c21e1" alt="Installation commands" width="1262" height="1214" data-path="enterprise/images/install-commands.png" />

### 4. Access the Admin Console

Once the install command completes, the Admin Console is available at:

* `https://<your-base-domain>:30000` (if you provided TLS certificates)
* `http://<your-vm-ip>:30000` (if you did not use the `--tls-cert` and `--tls-key` flags on the `install` command)

If you did not provide TLS certificates with the `install` command, your browser will display a security warning.
Click **Advanced**, then **Proceed** to continue to the Admin Console.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/self-signed-cert-warning.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=452af87d411205138638b53d60f8035c" alt="Self-signed certificate warning" width="1263" height="1214" data-path="enterprise/images/self-signed-cert-warning.png" />

### 5. Upload TLS certificate (if not provided with the install command)

If you did not provide certificates with the `install` command, select **"Upload your own"**,
enter your base domain under **Hostname**, upload your private key and SSL certificate, then click **Continue**.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/upload-tls-certificate.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=d1b68e7f4f1f6fe60562aa00c4780aaf" alt="Upload TLS certificate" width="1263" height="1211" data-path="enterprise/images/upload-tls-certificate.png" />

### 6. Log in to the Admin Console

Enter the password you set during installation and click **Log in**.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/admin-console-login.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=14ce8c0c375e86a57202936a8f9f9cd3" alt="Admin Console login" width="1269" height="1211" data-path="enterprise/images/admin-console-login.png" />

### 7. Configure the cluster

You will be prompted to add additional nodes to the cluster.
For a single-node deployment, click **Continue** to skip this step.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/configure-cluster-nodes.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=5057296bc067d3f63a22d7d7dfb58ecb" alt="Configure cluster nodes" width="1319" height="1211" data-path="enterprise/images/configure-cluster-nodes.png" />

## Configure OpenHands

You should now see the application configuration page.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/configure-openhands.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=49d0dd640567080228c3746fdf3d175b" alt="Configure OpenHands" width="1312" height="1211" data-path="enterprise/images/configure-openhands.png" />

### Domain Configuration

* Select **"Derive hostnames from domain (recommended)"**
* Enter your base domain (e.g., `openhands.example.com`)

### Certificate Configuration

* Upload your **TLS Certificate** (`.crt` or `.pem`)
* Upload your **TLS Private Key** (`.key` or `.pem`)
* Optionally upload the root **CA Certificate** for your TLS certificates

### LLM Configuration

Enter your Anthropic API key from the [Anthropic Console](https://console.anthropic.com/).

### Sandbox Routing Configuration

Under **Sandbox Configuration**, select your **Sandbox Routing Mode**:

* **Subdomain** (default): Routes each sandbox at `{id}.runtime.<your-domain>`. Requires wildcard DNS and certificate.
* **Path-based**: Routes all sandboxes at `runtime.<your-domain>/{id}`. No wildcard DNS or certificate required.

<Info>
  Select **Path-based** if your certificate authority does not issue wildcard certificates
  or if your environment does not support wildcard DNS records.
</Info>

### GitHub Authentication

Enable GitHub Authentication in the Admin Console, then follow these steps to create and
configure a GitHub App.

#### Create a GitHub App

Run our [script](https://github.com/All-Hands-AI/OpenHands-Cloud/tree/main/scripts/create_github_app) to create a GitHub App configured for your install.

#### Map GitHub App values to Admin Console

Go back to the Installer Admin Console in your browser and enter the values from the Create GitHub App script output. For the private key, upload the file from the `keys` directory of the script location.

After filling in all fields, click **Continue** at the bottom of the page.

## Deploy and Verify

OpenHands will begin deploying. You can expect the deployment status to transition from
**Missing** to **Unavailable** to **Ready**. This typically takes 5-10 minutes.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/deployment-in-progress.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=874b98a6e44714117460f2fcf9c06ab3" alt="Deployment in progress" width="1319" height="1211" data-path="enterprise/images/deployment-in-progress.png" />

Click **Details** next to the deployment status to monitor individual resources. Resources
shown in orange are still deploying -- wait until all resources are ready.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/deployment-status-details.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=15623413ba7536e6f70bd3b98bb4a02a" alt="Deployment status details" width="1319" height="1211" data-path="enterprise/images/deployment-status-details.png" />

## First Login

Once the deployment status shows **Ready**, navigate to `https://app.<your-base-domain>`
and click the **Login with GitHub** tile.

Accept the Terms of Service and click **Continue**.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/accept-terms-of-service.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=67597122d5b7d28fad274f6a7ce80840" alt="Accept Terms of Service" width="1319" height="1211" data-path="enterprise/images/accept-terms-of-service.png" />

OpenHands Enterprise is now running. You can open a repository or start a new conversation.

<img src="https://mintcdn.com/allhandsai-docs-path-based-sandbox-routing-v2/RQntuvPNcjkXnzgG/enterprise/images/openhands-ready.png?fit=max&auto=format&n=RQntuvPNcjkXnzgG&q=85&s=d98618da1895f985163bf5af8d7fc3d1" alt="OpenHands is ready" width="1319" height="1211" data-path="enterprise/images/openhands-ready.png" />

## Next Steps

<CardGroup cols={2}>
  <Card title="Enterprise Overview" icon="building" href="/enterprise/index">
    Learn about OpenHands Enterprise features, integrations, and deployment options.
  </Card>

  <Card title="Prompting Best Practices" icon="lightbulb" href="/openhands/usage/tips/prompting-best-practices">
    Get the most out of your AI coding agents with effective prompting techniques.
  </Card>

  <Card title="Contact Support" icon="headset" href="https://openhands.dev/contact">
    Reach out to the OpenHands team for deployment assistance or questions.
  </Card>

  <Card title="OpenHands Documentation" icon="book" href="/overview/introduction">
    Explore the full OpenHands documentation for usage guides and features.
  </Card>
</CardGroup>
