The operator uses existing cloud, Kubernetes or host-admin permissions.
1. Local managed harness process
Your backend owns a Rust child process. The browser talks to your application; the harness has no public API port.
Start with a self-contained application. For a prototype, an internal tool, or a coding lab with one container per learner, the application can run its own harness and tools together. You get a working agent without operating a separate agent service. This fits when the application and its agent workload can be deployed and scaled as one unit.
- StartThe SDK launches the harness and connects over private stdio.
- SubmitYour backend creates an agent/session and sends a message.
- ExecuteThe harness calls the model and ToolRunner, recording execution state.
- ReturnEvents and results flow back through the SDK to your UI.
Minimal TypeScript
import { Harness } from "@openworker/harness";
const harness = await Harness.start({
stateDir: "/state/openworker",
sandbox: "off", // Explicit dedicated-container development profile.
modelProviders: [primaryProvider],
});
const coder = harness.createAgent({
name: "coder",
instructions: "Build and test browser applications.",
tools: ["coding.read_file", "coding.write_file", "coding.run_shell"],
defaultModel: selectedModel,
});
const session = await coder.newSession({ workspace: "/workspace" });
const run = await session.send("Build and test a quiz app.");
for await (const event of run.events()) {
forwardToUI(event); // Text, tools, plans and pending interactions.
}
const result = await run.result();Linux development example: primaryProvider and selectedModel are application-supplied configuration. Model keys stay in the backend. sandbox: "off" adds no OS isolation; use a dedicated container or select a supported sandbox for the workload. The app supervises the child, and shutdown stops its execution resources.
2. Service cluster: compute and execution on one node
Your backend connects to the service. A harness worker and its OpenShell sandbox share a node, while remaining separate execution boundaries.
Scale agent capacity independently of your web application. As more users submit tasks, your web servers and agent workers may need different amounts of capacity. A service cluster lets several application backends submit work to a shared worker pool. Keeping each worker and its sandbox on the same node gives you a straightforward execution layout while you scale the pool.
- AdmitThe API checks caller, agent release, RuntimeProfile and idempotency key.
- SchedulePostgreSQL records the request. A compatible worker claims the session.
- AttachThe profile places the sandbox beside the worker; tools run inside it.
- ObserveThe worker records events. Any API replica can replay them over SSE.
Minimal TypeScript
import { Harness } from "@openworker/harness";
const service = await Harness.connect({
url: process.env.OPENWORKER_URL,
namespace: "my-product",
credentials: { tokenEnv: "OPENWORKER_TOKEN" },
});
const coder = await service.agent("coder@v1"); // Already deployed + active.
const session = await coder.newSession({
runtimeProfile: "openshell-colocated",
idempotencyKey: "project-42-coder", // Reuse only for this creation intent.
});
await saveProjectEnvironment(session.environmentId);
const run = await session.send("Build and test a quiz app.");
for await (const event of run.events()) {
forwardToUI(event); // Text, tools, plans and pending interactions.
}
const result = await run.result();Proposed service API. An administrator has already deployed coder@v1, configured its model provider, and granted access to the profile. Strict same-node placement needs provider/scheduler support and verification; it must not be inferred from “same cluster” or silently relaxed.
3. Service cluster: execution on separate compute
The agent loop stays on service workers. ToolRunner and files live on a separate execution node, cluster or provider.
Give workspaces their own resources and lifetime. An app builder may keep a project workspace around between conversations, while some builds need far more CPU or memory than the agent loop. Separate execution lets you size sandbox capacity independently and retain project storage when execution stops. It also gives you a place to add specialized or external execution providers without moving your application backend.
- SelectThe application chooses an approved remote RuntimeProfile.
- BindThe service provisions or verifies the original execution and storage identities.
- ExecuteThe provider channel carries tool requests/results across the boundary.
- RecoverA lost result becomes an explicit unknown outcome; no blind tool replay.
Minimal TypeScript
import { Harness } from "@openworker/harness";
const service = await Harness.connect({
url: process.env.OPENWORKER_URL,
namespace: "my-product",
credentials: { tokenEnv: "OPENWORKER_TOKEN" },
});
const coder = await service.agent("coder@v1"); // Already deployed + active.
const session = await coder.newSession({
runtimeProfile: "openshell-remote",
idempotencyKey: "project-42-coder", // Reuse only for this creation intent.
});
await saveProjectEnvironment(session.environmentId);
const run = await session.send("Build and test a quiz app.");
for await (const event of run.events()) {
forwardToUI(event); // Text, tools, plans and pending interactions.
}
const result = await run.result();OpenShell first. External-provider adapters require separate qualification. Model credentials stay on workers; execution receives only scoped tool credentials. A lost execution connection may leave a process running. Switching profiles does not migrate live files/processes.
Who authorizes the first administrator?
The trusted installer. This works on cloud infrastructure, local Kubernetes and individual machines.
A private job creates an administrator record and a random, expiring token. Only its hash enters the auth registry.
The token goes to a restricted secret store or owner-only file. The installer retrieves it using existing authority.
The CLI presents the token over TLS. Set up normal identities, test another administrator, then revoke bootstrap.
| Deployment | Installer authority | Token destination |
|---|---|---|
| Cloud Kubernetes | Cloud / Kubernetes credentials | Restricted secret manager or Kubernetes Secret |
| Local Kubernetes | Kubernetes administrator credentials | Restricted Kubernetes Secret |
| Docker / bare metal | Host administrator access | Owner-only private local file |
# Proposed CLI; token was delivered privately by installation.
ows login --url https://agents.example.com --token-file /private/bootstrap-tokenNo public “first caller becomes admin” endpoint. Repeating installation must not replace the administrator. Bootstrap retries reconcile the original operation; expired credentials do not reopen registration.
Terraform configures infrastructure, certificate integration and secret-store access—not a long-lived admin token in its state. Local clusters use trusted TLS certificates too; only explicit loopback development allows HTTP. Service tokens, model credentials and internal mTLS identities are separate.
Who controls cluster size?
| Layer | Owns |
|---|---|
| Terraform / infrastructure operator | Cluster, node types, node-count bounds, IAM, storage and database |
| Helm | Installed service, worker pools, UI and controllers |
| Kubernetes autoscalers | Capacity adjustments within configured bounds |
ows / REST / management UI | Worker capacity, admission quotas, RuntimeProfiles and configuration revisions |
Customers may bring an existing cluster; Terraform is optional. A pool has one scaling authority—manual, autoscaled or GitOps—to avoid competing writes. The UI uses the same REST API, with no direct database or cluster-admin access.