Prompts

OpenHands Self-Hosting Guide: Run Autonomous AI Coding Agents Locally

Back to Tutorials

What self-hosting OpenHands actually protects

Self-hosting OpenHands is not the same as making every part of an agent workflow private. It usually means that the OpenHands interface, agent server, runtime orchestration, conversations, and repository workspace run under infrastructure you control. The language model provider is a separate decision.

There are two distinct data paths:

  1. Self-hosted OpenHands with a hosted model provider. Your OpenHands service and Docker runtime may be local, but prompts, code excerpts, tool results, and other context sent to the model can still leave your network.
  2. Self-hosted OpenHands with a local model. The agent and model can remain on your machine or private network, subject to the model server and networking configuration you choose.

That distinction should appear in your threat model and in your prompts. A prompt cannot prevent a model provider from receiving content that the agent sends to it. If code must never leave a controlled network, use a model endpoint that satisfies that requirement and verify the network path independently.

OpenHands is designed for work beyond autocomplete: inspecting a repository, planning changes, editing files, executing commands, running tests, and producing a reviewable result. That autonomy is useful precisely because the agent can take actions. It also means that a Docker sandbox, a restricted workspace, scoped credentials, and explicit approval boundaries are more important than a clever one-line prompt.

A sensible first deployment is deliberately boring:

  • Run the OpenHands application and agent runtime locally.
  • Give each task a disposable branch or working directory.
  • Mount only the repository and directories the task needs.
  • Keep provider keys outside the repository and outside prompts.
  • Start with read-only or low-privilege integrations.
  • Require tests and a human review before merging or deploying.

Docker isolation reduces the blast radius of commands executed by the agent, but it is not a complete security boundary by itself. Review Docker privileges, mounted paths, network access, exposed ports, image provenance, host permissions, and the credentials available to the runtime. Do not assume that a container automatically makes arbitrary secrets safe.

Deployment planning before you write a prompt

Inputs to collect

Before launching a task, write down:

  • The repository or subdirectory the agent may modify.
  • The exact goal and the acceptance criteria.
  • The test, lint, type-check, or build commands that are allowed.
  • Files that are off limits, such as deployment manifests or production configuration.
  • Whether internet access is required.
  • Which external services are necessary, if any.
  • The maximum change scope: for example, one endpoint, one package, or one migration.
  • The required output: patch, commit, test report, pull request description, or diagnosis.

This information turns an open-ended request into a bounded engineering task. “Improve the authentication system” gives the agent too much room. “Add a failing test for expired access tokens, implement the smallest fix, run the authentication test suite, and do not change token storage” is much easier to inspect.

Outputs to require

An autonomous agent should not merely say that it finished. Ask it to return:

  • A concise summary of changed files.
  • The reason for each meaningful change.
  • Commands executed and their exit status.
  • Tests that passed, failed, or were skipped.
  • Assumptions made because the repository was ambiguous.
  • Known limitations and follow-up work.
  • Any file or command it wanted to access but could not.

These outputs create an audit trail for a human reviewer and expose incomplete work. They also help you distinguish “the code was edited” from “the task was actually validated.”

Security policy design

Keep security policy decisions separate from task instructions. A task prompt should describe what the agent is trying to accomplish. The runtime policy should decide what it is allowed to touch and execute.

A useful policy review asks:

  • Can the runtime write outside the intended workspace?
  • Can it read the host filesystem through mounts or environment variables?
  • Can it access the network, and if so, which destinations are needed?
  • Can it read shell history, cloud credentials, SSH keys, package-manager tokens, or Git credentials?
  • Can it install packages or execute privileged operations?
  • Are credentials passed only to the process that needs them?
  • Are logs and conversation records protected from unauthorized readers?

Use the OpenHands and Docker documentation for the exact configuration syntax for your installed 1.x release. Configuration names and supported policy controls can change between releases; do not copy an old example without checking the version-specific documentation.

The safe pattern is to provide credentials through the runtime’s supported secret mechanism, environment injection, or a narrowly scoped credential helper. Never paste an API key into a task prompt, commit it into a repository, place it in an example file that will be mounted into the container, or ask the agent to discover it from the host. If a key is exposed in a conversation or command output, rotate it.

Prompt templates for OpenHands coding tasks

The templates below are intentionally explicit. They are not replacements for container policy. They are task-level controls that make the agent’s decisions easier to review.

Template 1: Safe repository reconnaissance

Inputs: repository path, objective, allowed inspection commands, and prohibited changes.

Output: architecture notes, risks, proposed plan, and no file modifications.

You are performing repository reconnaissance only.

Repository scope:
- Work only inside: <REPOSITORY_OR_SUBDIRECTORY>
- Do not modify files, create commits, install packages, or contact external services.

Objective:
<DESCRIBE_THE_PROBLEM_OR_FEATURE>

Inspect the repository using read-only operations. Identify:
1. The relevant entry points and modules.
2. Existing tests and the command used to run them.
3. Configuration, environment variables, and integration boundaries that matter.
4. Conventions the implementation should follow.
5. Ambiguities or risks that require a human decision.

Return:
- A short architecture summary.
- A list of relevant files with one-line explanations.
- A proposed implementation plan with ordered steps.
- The exact tests you recommend running.
- A list of questions or assumptions.

Stop after the report. Do not edit anything.

This is a useful first pass for unfamiliar repositories. It prevents the common failure mode where the agent begins changing code before it understands the project’s test layout or configuration model.

Template 2: Bounded implementation with tests

Inputs: approved plan, change scope, acceptance criteria, and permitted commands.

Output: implementation plus a validation report.

Implement the approved change below.

Approved plan:
<PASTE_THE_REVIEWED_PLAN>

Scope:
- You may modify only: <LIST_FILES_OR_DIRECTORIES>
- Do not modify: <LIST_PROTECTED_FILES>
- Do not change public APIs, database schemas, dependency versions, or deployment configuration unless explicitly listed below.

Acceptance criteria:
- <CRITERION_1>
- <CRITERION_2>
- <CRITERION_3>

Rules:
1. Inspect existing code and tests before editing.
2. Prefer the smallest compatible change.
3. Follow the repository’s existing style and error-handling conventions.
4. Add or update focused tests for the behavior you change.
5. Do not place secrets in source files, tests, logs, prompts, or output.
6. Do not run destructive commands or alter data outside the task workspace.
7. If the plan is impossible or the acceptance criteria conflict, stop and explain the blocker instead of improvising.

Validation:
Run only these commands unless an additional command is clearly necessary:
<ALLOWED_TEST_AND_CHECK_COMMANDS>

Final report must include:
- Changed files.
- Behavior implemented.
- Commands run and results.
- Tests added or updated.
- Assumptions, failures, and remaining risks.

The important design choice is the explicit stop condition. Without it, an agent may silently expand the task when it encounters a missing dependency, an unclear requirement, or a failing test.

Template 3: Debugging without speculative rewrites

Inputs: failure output, reproduction steps, relevant module, and permitted test command.

Output: root-cause analysis, minimal fix, and evidence.

Debug the failure described below. Do not perform a broad refactor.

Failure:
<ERROR_MESSAGE_AND_RELEVANT_LOGS>

Reproduction:
<STEPS_OR_TEST_NAME>

Scope:
- Inspect and modify only: <SCOPE>
- Preserve the current public behavior except for the bug fix.
- Do not suppress the error, weaken assertions, delete tests, or replace the component wholesale.

Process:
1. Reproduce the failure if possible.
2. Trace the failing path to a specific root cause.
3. State the root cause before editing.
4. Add a regression test that fails before the fix when practical.
5. Apply the smallest fix.
6. Run the focused test and the relevant broader suite.

If reproduction is not possible, stop and report what evidence is missing. Do not claim the issue is fixed without test evidence.

Return:
- Root cause.
- Files changed.
- Regression test.
- Validation commands and results.
- Any unverified assumptions.

Template 4: Review an agent-generated patch

Inputs: diff, task specification, test results, and risk classification.

Output: review findings sorted by severity.

Review the current working-tree diff as a skeptical senior engineer.

Task specification:
<TASK_AND_ACCEPTANCE_CRITERIA>

Review for:
- Incorrect behavior and missed edge cases.
- Security, authorization, privacy, and secret-handling problems.
- Breaking API or data-compatibility changes.
- Race conditions, resource leaks, and failure handling.
- Tests that assert implementation details but miss user-visible behavior.
- Unrelated changes or scope expansion.

Do not modify files. Do not approve based only on a passing test suite.

Return findings in this format:
1. Severity: blocker/high/medium/low
2. File and location
3. Concrete problem
4. Why it matters
5. A focused recommendation

Then provide:
- What the patch does well.
- Which acceptance criteria are demonstrated.
- Which checks are still missing.
- A final recommendation: approve, request changes, or unable to assess.

Operating tips that make prompts work better

Separate facts, instructions, and evidence

Use labeled sections such as Task, Scope, Constraints, Allowed commands, and Evidence. Do not bury critical restrictions in a long narrative. Put repository-specific facts in the prompt, but keep secrets and unnecessary sensitive data out of it.

Give the agent a narrow first action

Reconnaissance, planning, implementation, and review are different stages. Combining all four into one request makes failures harder to diagnose. For risky work, run a read-only plan first, review it, then issue an implementation prompt.

Prefer acceptance tests over adjectives

“Production quality” is not an acceptance criterion. “Reject an expired token with the existing error type, preserve the response shape, and add coverage for a one-second expiry boundary” is testable.

Treat command access as a capability

Tell the agent exactly which checks it may run. A sandbox policy should enforce the important boundary, while the prompt communicates the intended workflow. If internet access is unnecessary, disable or restrict it rather than merely asking the agent not to browse.

Make failures visible

Require the agent to report skipped tests, unavailable services, changed assumptions, and commands that failed. Never accept “all done” as evidence. A passing formatter does not prove that the feature works; a focused unit test does not prove that the integration still works.

Use disposable workspaces

Run autonomous tasks against a branch, temporary clone, or disposable workspace. Review the diff before merging. For migrations, deployment files, authentication, payment code, and data deletion, use a stronger approval process than for routine documentation changes.

Test the data path, not just the UI

If privacy is the reason for self-hosting, verify which component receives prompts and code. Inspect provider settings, runtime networking, logs, mounted files, and telemetry. A local web interface does not prove that model requests remain local.

Common failure modes

The agent edits too much. Reduce the allowed scope, list protected files, and require a plan before implementation.

The agent claims success after a failed test. Require command results and a stop condition for unresolved failures.

A credential appears in output. Stop the run, revoke or rotate the credential, inspect logs, and determine how it became visible. Then tighten secret injection and shell access.

The model cannot complete complex work locally. Local execution improves control over the data path but does not guarantee model quality. Break the task into smaller stages, use stronger hardware or a different approved model, and keep human review.

The sandbox is treated as a complete security boundary. Review container privileges, mounts, network access, image updates, and host permissions. Use defense in depth.

The setup is operationally neglected. Self-hosting transfers responsibility to you: upgrades, backups, access control, resource limits, logs, vulnerability response, and model-provider configuration all need owners.

FAQ

Does self-hosting OpenHands keep my source code completely private?

Not automatically. The OpenHands service and Docker runtime can be self-hosted while model requests still go to an external provider. For an all-local data path, use a local model endpoint and verify that prompts, tool results, logs, and telemetry do not leave the intended network.

Are Docker sandboxes safe for arbitrary autonomous commands?

They are a useful isolation layer, not a guarantee of safety. Limit mounts, privileges, network access, and credentials. Use disposable workspaces, keep the host updated, and review changes before they reach shared or production systems.

Where should OpenHands API keys be stored?

Use the supported runtime secret or environment-injection mechanism for your deployment. Do not put keys in prompts, source code, committed environment files, shell history, or mounted directories that the agent does not need. Scope and rotate credentials regularly.

Should I give the agent the whole repository?

Only when the task genuinely requires it. Start with the smallest repository scope that provides enough context. Restrict sensitive directories and avoid mounting unrelated home-directory or infrastructure credentials.

What should a good autonomous coding prompt contain?

It should define the goal, scope, acceptance criteria, permitted commands, prohibited actions, stop conditions, and required final report. The runtime policy must enforce security boundaries; the prompt should make the intended task and evidence requirements unambiguous.

When should a human approve the work?

At minimum, review every autonomous change before merging. Add explicit approval before external side effects, production deployments, destructive data operations, permission changes, dependency upgrades, and modifications to authentication or secret-handling code.