DocsHarness SDK

BEEOS CLOUD / DEVELOPER REFERENCE

Install and authenticate

Install the Harness SDK, understand the credentials a harness uses, and initialise the client for each call source.

This page installs the packages, explains which credential protects which call, and shows how to initialise the client for each call source. Every example runs against the published packages.

Install

npm install @beeos-ai/cloud-harness-sdk@1.0.0
LanguageRequires
TypeScriptNode.js ≥ 22. The package is ESM only ("type": "module").
PythonPython ≥ 3.11. The package root (beeos_cloud_harness_sdk) uses only the standard library; the submodules in this reference need httpx and cryptography, which pip installs.

Credentials

A harness never holds a Cloud API key. It uses the credentials below, each for one call source.

Call sourceCredentialHow it is sentSDK entry points
Agent GatewayEd25519 signature of the harness key pairFour headers: X-Agent-Public-Key, X-Agent-Signature, X-Agent-Timestamp, X-Agent-Nonce. The signed text is `METHODPATH
Registration and heartbeatIdentity proof signed with the instance identity key, sent through Agent GatewayA signed proof inside the request body (domains beeos.runtime.registration.v1 and beeos.runtime.heartbeat.v1).Registration and lease
Message Service (deliveries, claims, chat)Runtime lease credential returned by registration and heartbeatAuthorization: Bearer <credential>. Some routes also need X-BeeOS-Execution-Grant or X-Runtime-Delivery-Key.Receiving runtime methods, Chat replies and realtime
Realtime eventsRealtime token, created with the lease credentialToken passed to the realtime client.Chat replies and realtime
Canvas relayCanvas token plus a signed upgrade requestSigned X-Agent-* headers on the WebSocket upgrade to /ws/agent; the token goes into the query.Canvas relay and terminal bridge
Terminal bridgeLease-bound agent_auth frame signed with the harness keyFirst frame of the connection; the bridge answers auth_ok.Canvas relay and terminal bridge
Execution grants (TypeScript only)RS256 signature checked against Cloud's published key setThe grant arrives with a delivery; the SDK only verifies it.Execution grant verification
Python facade BeeOSAgentRuntime (Python only)One bearer tokenAuthorization header; a value without a space gets Bearer in front.Python agent runtime

Initialise the client

Key pair and Agent Gateway

Load or create the harness key pair, then build the signed Agent Gateway client. The private key stays in your process.

import { AgentGatewayClient, agentIdentityFromKeyPair, loadAgentKeyPair } from "@beeos-ai/cloud-harness-sdk";

const keys = loadAgentKeyPair("./harness-key.json");
const gateway = new AgentGatewayClient({
  baseUrl: process.env.AGENT_GATEWAY_URL!,
  identity: agentIdentityFromKeyPair(keys),
});

// Every call is signed with the harness key and re-signed on each retry.
const canvasToken = await gateway.canvas.token();
console.log(canvasToken.relayUrl);

Register and keep the lease

The coordinator registers the runtime, sends signed heartbeats and tells you when the lease is lost. Declare only the runtime methods and capabilities that your harness really handles. The TypeScript example passes the identity fields itself; the Python example keeps them in an identity file.

import { createHash, randomUUID } from "node:crypto";
import {
  AgentGatewayClient,
  InstanceAuthorityRuntimeRegistrationTransport,
  RuntimeRegistrationCoordinator,
  agentIdentityFromKeyPair,
  loadAgentKeyPair,
} from "@beeos-ai/cloud-harness-sdk";

// 1. Harness key pair. The file is created with mode 0600 when it does not exist.
const keys = loadAgentKeyPair("./harness-key.json");
const identity = agentIdentityFromKeyPair(keys);

// 2. Signed client for Agent Gateway.
const gateway = new AgentGatewayClient({
  baseUrl: process.env.AGENT_GATEWAY_URL!,
  identity,
});

// 3. Register and keep the lease alive. Persist registrationId and journalStoreId between restarts.
const registrationId = randomUUID();
const coordinator = new RuntimeRegistrationCoordinator(
  new InstanceAuthorityRuntimeRegistrationTransport({ gateway, registrationId }),
  {
    registrationId,
    handlerIdentity: "my-harness-1",
    contractRevision: "2026-07-14.3",
    runtimeMethods: ["session/prompt"],
    capabilities: ["transport", "conversation.control"],
    manifestDigest: process.env.RUNTIME_MANIFEST_DIGEST!, // SHA-256 digest of the method manifest you implement
    journalStoreId: randomUUID(),
    journalGeneration: "1",
    instanceIdentityKeyId: createHash("sha256").update(keys.publicKey).digest("hex"),
    targetInstanceId: process.env.BEEOS_INSTANCE_ID,
    signIdentityProof: message => identity.sign(message),
  },
  (reason, cause) => console.error("runtime lease lost:", reason, cause),
);

const lease = await coordinator.start();
if (lease) console.log("lease expires at", lease.leaseExpiresAt);
// ... later: coordinator.stop();

instanceIdentityKeyId is the SHA-256 hex digest of the public key, as the Python coordinator computes it. manifestDigest has no default in TypeScript; Python defaults it to RUNTIME_CURRENT_MANIFEST_DIGEST.

Python agent runtime facade

Only the Python package has this facade. It authenticates with one bearer token and dispatches chat messages, cancellations and runtime methods to your handlers.

import os
from typing import Any

from beeos_cloud_harness_sdk import BeeOSAgentRuntime

runtime = BeeOSAgentRuntime(
    agent_gateway_url=os.environ["AGENT_GATEWAY_URL"],
    message_service_url=os.environ["MESSAGE_SERVICE_URL"],
    instance_id=os.environ["BEEOS_INSTANCE_ID"],
    agent_id=os.environ["BEEOS_AGENT_ID"],
    token=lambda: os.environ["BEEOS_RUNTIME_TOKEN"],  # a string or a function that returns the current one
)

def on_chat_message(event: dict[str, Any]) -> None:
    # Cloud pre-creates the reply message; complete it with the answer.
    runtime.chat.complete_reply(event["conversationId"], event["replyMessageId"], "You said: " + event["text"])

runtime.register(on_chat_message=on_chat_message)

Handling credentials

  • Keep the key file private. The SDK creates it with mode 0600.
  • The lease credential, execution grants and delivery keys are secrets. Never log or persist them; the SDK sends each of them only to its own origin and refuses redirects.
  • Registration, heartbeat and appends are not replayed blindly. Retry and failure handling are described in the retry module.

Next: Registration and lease, Receiving runtime methods, Retry and HTTP errors.