Skip to main content
sec0-sdk/integrations/openclaw exports three integration helpers:
  • createMoltbotHooks(...)
  • createMoltbotPlugin(...)
  • createMoltbotEscalationManager(...)
Use them when you want Sec0 policy enforcement inside an OpenClaw or Moltbot runtime without reimplementing audit, policy loading, or escalation glue. For non-OpenClaw applications, use createEscalationManager(...) from sec0-sdk/escalation directly. createMoltbotEscalationManager(...) is now a thin OpenClaw adapter over that shared approvals lifecycle.

Minimal Plugin

const { createMoltbotPlugin } = require("sec0-sdk/integrations/openclaw");

module.exports = createMoltbotPlugin((api) => ({
  policyPath: api.resolvePath("policies/policy.yaml"),
  auditDir: api.resolvePath("~/.moltbot/sec0/audit"),
  signingKeyPath: api.resolvePath("~/.moltbot/sec0/ed25519.b64"),
  tenant: "acme",
  serverName: "moltbot-gateway@prod",
  mode: "enforce",
}));

Manual Hook Wiring

Use createMoltbotHooks(...) when you want full control over how the runtime registers handlers:
const { createMoltbotHooks } = require("sec0-sdk/integrations/openclaw");

module.exports = async function sec0Plugin(api) {
  const hooks = createMoltbotHooks({
    policyPath: api.resolvePath("policies/policy.yaml"),
    auditDir: api.resolvePath("~/.moltbot/sec0/audit"),
    signingKeyPath: api.resolvePath("~/.moltbot/sec0/ed25519.b64"),
    tenant: "acme",
    serverName: "moltbot-gateway@prod",
    mode: "enforce",
  });

  api.on("before_tool_call", hooks.beforeToolCall, { priority: 100 });
  api.on("after_tool_call", hooks.afterToolCall, { priority: -10 });
};

Control-Plane Policy

You can load policy from the Sec0 control plane instead of a local file:
const hooks = createMoltbotHooks({
  policyFromControlPlane: true,
  policyRefreshMs: 30000,
  apiKey: process.env.SEC0_API_KEY,
  auditDir: api.resolvePath("~/.moltbot/sec0/audit"),
  signingKeyPath: api.resolvePath("~/.moltbot/sec0/ed25519.b64"),
  tenant: "acme",
  serverName: "moltbot-gateway@prod",
  mode: "enforce",
});
Use policyControlPlaneSource when you need a specific level, scope, or node override.

Configuration

Required

OptionDescription
policyPath or policyYaml or policyObjectPolicy source
auditDirDirectory for audit logs
signingKeyPathPath to Ed25519 key
tenantTenant identifier
serverNameServer identity (name@version)
mode"observe" or "enforce"

Common Optional Fields

OptionDescription
allowlistOverride policy.tools.allowlist
policyFromControlPlaneFetch policy from the control plane
policyControlPlaneSourceOverride control-plane level, scope, node, and fallback settings
policyRefreshMsPolicy refresh TTL in milliseconds
agentGuardAgent Guard options or false
skillsSee Skills Hooks for resolver and scan hook configuration
complianceNL or regex compliance configuration
onDecisionDecision callback
onAuditErrorAudit error callback
gatewayToolRegister a bridge-backed tool that routes through callToolViaGateway(...)
messagesGovern inbound or outbound messages in addition to tool calls

Skills Hooks

Skill resolver and scanning behavior has moved to Skills Hooks. Use that section for skills.resolve, skills.onScan, and policy reason mapping.

Message Governance

Enable inbound or outbound message scanning alongside tool calls:
const hooks = createMoltbotHooks({
  // ...base config...
  messages: {
    enabled: true,
    direction: "both",
    audit: true,
    storeContent: false,
    quarantine: { enabled: true, ttlMs: 3600000 },
  },
});

const result = await hooks.messageSending?.({ to: "user", content: "..." }, ctx);
if (result?.cancel) {
  // blocked
}
if (result?.escalate) {
  // send through createMoltbotEscalationManager(...)
}

Escalation Manager

Use the built-in OpenClaw escalation adapter instead of hand-writing create, poll, and resolve logic in your app:
import {
  createMoltbotHooks,
  createMoltbotEscalationManager,
} from "sec0-sdk/integrations/openclaw";
import { createEscalationManager } from "sec0-sdk/escalation";

const hooks = createMoltbotHooks(cfg);
const sharedEscalationManager = createEscalationManager({
  apiKey: process.env.SEC0_API_KEY,
  controlPlaneUrl: process.env.SEC0_CONTROL_PLANE_URL,
  tenant: process.env.SEC0_TENANT_ID,
  timeoutMs: 5 * 60_000,
  pollIntervalMs: 2000,
  defaults: {
    ttlSeconds: 300,
    timeoutAction: "auto_reject",
  },
});
const escalation = createMoltbotEscalationManager({
  escalationMode: "human",
  manager: sharedEscalationManager,
  waitForResolution: true,
});

const gate = await hooks.messageSending?.({ to, content, metadata }, ctx);
const decision = await escalation.handle({
  gateResult: gate,
  nodeId: ctx?.accountId,
  agentRef: ctx?.conversationId,
  metadata: { turn: 3 },
});

if (!decision.allow) {
  return;
}
await sendToChannel(content);
Supported modes are human, auto-approve, auto-reject, and off. Pass reporter and resolver directly if you want custom backends. Pass manager when you want one shared escalation lifecycle reused across OpenClaw hooks and the rest of your application.

Gateway Tool Registration

gatewayTool registers a bridge-backed tool inside the host runtime:
const hooks = createMoltbotHooks({
  // ...base config...
  gatewayTool: {
    enabled: true,
    name: "sec0.call_gateway",
    defaults: {
      gatewayBaseUrl: "https://gateway.example.com",
      server: "payments-mcp",
      toolAtVersion: "charge@1.0",
    },
  },
});
The host can then call the registered tool and let Sec0 build the bridge request.

Human Escalation Policy

Route high-risk actions to approval instead of hard-blocking:
security:
  side_effects:
    approve_high_risk: true
enforcement:
  escalate_on:
    - agent_guard_failed

OpenTelemetry

sec0-sdk/otel provides helpers for bootstrapping tracing:
import { initTracing } from "sec0-sdk/otel";

initTracing({
  endpoint: "http://localhost:4317",
  serviceName: "my-tool-server",
  serviceVersion: "1.0.0",
  environment: "dev",
  tenant: "my-app",
  sample: { success: 1, error: 1 },
});
See the Signer & OTel Reference for the full API.