TaskFlow
DashboardFreewriteWhiteboardsProjectsCRMTasksNotificationsSettingsAgent TowerAPI Docs
OpenClaw Docs
?

User

Member

Caricamento in corso...

Home
Progetti
Task
Notifiche
CRM

    OpenClaw

    Documentation Mirror

    Documentation Overview

    Docs

    Auth credential semantics
    Scheduled tasks
    Hooks
    Automation & tasks
    Standing orders
    Task flow
    Background tasks
    BlueBubbles
    Broadcast groups
    Channel routing
    Discord
    Feishu
    Google Chat
    Group messages
    Groups
    iMessage
    Chat channels
    IRC
    LINE
    Channel location parsing
    Matrix
    Matrix migration
    Matrix push rules for quiet previews
    Mattermost
    Microsoft Teams
    Nextcloud Talk
    Nostr
    Pairing
    QA channel
    QQ bot
    Signal
    Slack
    Synology Chat
    Telegram
    Tlon
    Channel troubleshooting
    Twitch
    WeChat
    WhatsApp
    Yuanbao
    Zalo
    Zalo personal
    CI pipeline
    ACP
    Agent
    Agents
    Approvals
    Backup
    Browser
    Channels
    Clawbot
    `openclaw commitments`
    Completion
    Config
    Configure
    Cron
    Daemon
    Dashboard
    Devices
    Directory
    DNS
    Docs
    Doctor
    Flows (redirect)
    Gateway
    Health
    Hooks
    CLI reference
    Inference CLI
    Logs
    MCP
    Memory
    Message
    Migrate
    Models
    Node
    Nodes
    Onboard
    Pairing
    Plugins
    Proxy
    QR
    Reset
    Sandbox CLI
    Secrets
    Security
    Sessions
    Setup
    Skills
    Status
    System
    `openclaw tasks`
    TUI
    Uninstall
    Update
    Voicecall
    Webhooks
    Wiki
    Active memory
    Agent runtime
    Agent loop
    Agent runtimes
    Agent workspace
    Gateway architecture
    Channel docking
    Inferred commitments
    Compaction
    Context
    Context engine
    Delegate architecture
    Dreaming
    Experimental features
    Features
    Markdown formatting
    Memory overview
    Builtin memory engine
    Honcho memory
    QMD memory engine
    Memory search
    Messages
    Model failover
    Model providers
    Models CLI
    Multi-agent routing
    OAuth
    OpenClaw App SDK
    Presence
    QA overview
    Matrix QA
    Command queue
    Steering queue
    Retry policy
    Session management
    Session pruning
    Session tools
    SOUL.md personality guide
    Streaming and chunking
    System prompt
    Timezones
    TypeBox
    Typing indicators
    Usage tracking
    Date and time
    Node + tsx crash
    Diagnostics flags
    Authentication
    Background exec and process tool
    Bonjour discovery
    Bridge protocol
    CLI backends
    Configuration — agents
    Configuration — channels
    Configuration — tools and custom providers
    Configuration
    Configuration examples
    Configuration reference
    Diagnostics export
    Discovery and transports
    Doctor
    Gateway lock
    Health checks
    Heartbeat
    Gateway runbook
    Local models
    Gateway logging
    Multiple gateways
    Network model
    OpenAI chat completions
    OpenResponses API
    OpenShell
    OpenTelemetry export
    Gateway-owned pairing
    Prometheus metrics
    Gateway protocol
    Remote access
    Remote gateway setup
    Sandbox vs tool policy vs elevated
    Sandboxing
    Secrets management
    Secrets apply plan contract
    Security audit checks
    Security
    Tailscale
    Tools invoke API
    Troubleshooting
    Trusted proxy auth
    Debugging
    Environment variables
    FAQ
    FAQ: first-run setup
    FAQ: models and auth
    GPT-5.5 / Codex agentic parity
    GPT-5.5 / Codex parity maintainer notes
    Help
    Scripts
    Testing
    Testing: live suites
    General troubleshooting
    OpenClaw
    Ansible
    Azure
    Bun (experimental)
    ClawDock
    Release channels
    DigitalOcean
    Docker
    Docker VM runtime
    exe.dev
    Fly.io
    GCP
    Hetzner
    Hostinger
    Install
    Installer internals
    Kubernetes
    macOS VMs
    Migration guide
    Migrating from Claude
    Migrating from Hermes
    Nix
    Node.js
    Northflank
    Oracle Cloud
    Podman
    Railway
    Raspberry Pi
    Render
    Uninstall
    Updating
    Logging
    Network
    Audio and voice notes
    Camera capture
    Image and media support
    Nodes
    Location command
    Media understanding
    Talk mode
    Node troubleshooting
    Voice wake
    Pi integration architecture
    Pi development workflow
    Android app
    Platforms
    iOS app
    Linux app
    Gateway on macOS
    Canvas
    Gateway lifecycle
    macOS dev setup
    Health checks (macOS)
    Menu bar icon
    macOS logging
    Menu bar
    Peekaboo bridge
    macOS permissions
    Remote control
    macOS signing
    Skills (macOS)
    Voice overlay
    Voice wake (macOS)
    WebChat (macOS)
    macOS IPC
    macOS app
    Windows
    Plugin internals
    Plugin architecture internals
    Building plugins
    Plugin bundles
    Codex Computer Use
    Codex harness
    Community plugins
    Plugin compatibility
    Google Meet plugin
    Plugin hooks
    Plugin manifest
    Memory LanceDB
    Memory wiki
    Message presentation
    Agent harness plugins
    Building channel plugins
    Channel turn kernel
    Plugin entry points
    Plugin SDK migration
    Plugin SDK overview
    Building provider plugins
    Plugin runtime helpers
    Plugin setup and config
    Plugin SDK subpaths
    Plugin testing
    Skill workshop plugin
    Voice call plugin
    Webhooks plugin
    Zalo personal plugin
    OpenProse
    Alibaba Model Studio
    Anthropic
    Arcee AI
    Azure Speech
    Amazon Bedrock
    Amazon Bedrock Mantle
    Chutes
    Claude Max API proxy
    Cloudflare AI gateway
    ComfyUI
    Deepgram
    Deepinfra
    DeepSeek
    ElevenLabs
    Fal
    Fireworks
    GitHub Copilot
    GLM (Zhipu)
    Google (Gemini)
    Gradium
    Groq
    Hugging Face (inference)
    Provider directory
    Inferrs
    Inworld
    Kilocode
    LiteLLM
    LM Studio
    MiniMax
    Mistral
    Model provider quickstart
    Moonshot AI
    NVIDIA
    Ollama
    OpenAI
    OpenCode
    OpenCode Go
    OpenRouter
    Perplexity
    Qianfan
    Qwen
    Runway
    SGLang
    StepFun
    Synthetic
    Tencent Cloud (TokenHub)
    Together AI
    Venice AI
    Vercel AI gateway
    vLLM
    Volcengine (Doubao)
    Vydra
    xAI
    Xiaomi MiMo
    Z.AI
    Default AGENTS.md
    Release policy
    API usage and costs
    Credits
    Device model database
    Full release validation
    Memory configuration reference
    OpenClaw App SDK API design
    Prompt caching
    Rich output protocol
    RPC adapters
    SecretRef credential surface
    Session management deep dive
    AGENTS.md template
    BOOT.md template
    BOOTSTRAP.md template
    HEARTBEAT.md template
    IDENTITY template
    SOUL.md template
    TOOLS.md template
    USER template
    Tests
    Token use and costs
    Transcript hygiene
    Onboarding reference
    Contributing to the threat model
    Threat model (MITRE ATLAS)
    Formal verification (security models)
    Network proxy
    Agent bootstrapping
    Docs directory
    Getting started
    Docs hubs
    OpenClaw lore
    Onboarding (macOS app)
    Onboarding overview
    Personal assistant setup
    Setup
    Showcase
    Onboarding (CLI)
    CLI automation
    CLI setup reference
    ACP agents
    ACP agents — setup
    Agent send
    apply_patch tool
    Brave search
    Browser (OpenClaw-managed)
    Browser control API
    Browser troubleshooting
    Browser login
    WSL2 + Windows + remote Chrome CDP troubleshooting
    BTW side questions
    ClawHub
    Code execution
    Creating skills
    Diffs
    DuckDuckGo search
    Elevated mode
    Exa search
    Exec tool
    Exec approvals
    Exec approvals — advanced
    Firecrawl
    Gemini search
    Grok search
    Image generation
    Tools and plugins
    Kimi search
    LLM task
    Lobster
    Tool-loop detection
    Media overview
    MiniMax search
    Multi-agent sandbox and tools
    Music generation
    Ollama web search
    PDF tool
    Perplexity search
    Plugins
    Reactions
    SearXNG search
    Skills
    Skills config
    Slash commands
    Sub-agents
    Tavily
    Thinking levels
    Tokenjuice
    Trajectory bundles
    Text-to-speech
    Video generation
    Web search
    Web fetch
    Linux server
    Control UI
    Dashboard
    Web
    TUI
    WebChat

    OpenAPI Specs

    openapi
    TaskFlow
    docs/openclaw
    Original Docs

    Real-time Synchronized Documentation

    Last sync: 01/05/2026 07:01:45

    Note: This content is mirrored from docs.openclaw.ai and is subject to their terms and conditions.

    OpenClaw Docs

    v2.4.0 Production

    Last synced: Today, 22:00

    Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.

    Use this file to discover all available pages before exploring further.

    Gateway protocol

    The Gateway WS protocol is the single control plane + node transport for OpenClaw. All clients (CLI, web UI, macOS app, iOS/Android nodes, headless nodes) connect over WebSocket and declare their role + scope at handshake time.

    Transport

    • WebSocket, text frames with JSON payloads.
    • First frame must be a
      text
      connect
      request.
    • Pre-connect frames are capped at 64 KiB. After a successful handshake, clients should follow the
      text
      hello-ok.policy.maxPayload
      and
      text
      hello-ok.policy.maxBufferedBytes
      limits. With diagnostics enabled, oversized inbound frames and slow outbound buffers emit
      text
      payload.large
      events before the gateway closes or drops the affected frame. These events keep sizes, limits, surfaces, and safe reason codes. They do not keep the message body, attachment contents, raw frame body, tokens, cookies, or secret values.

    Handshake (connect)

    Gateway → Client (pre-connect challenge):

    json
    { "type": "event", "event": "connect.challenge", "payload": { "nonce": "…", "ts": 1737264000000 } }

    Client → Gateway:

    json
    { "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 3, "client": { "id": "cli", "version": "1.2.3", "platform": "macos", "mode": "operator" }, "role": "operator", "scopes": ["operator.read", "operator.write"], "caps": [], "commands": [], "permissions": {}, "auth": { "token": "…" }, "locale": "en-US", "userAgent": "openclaw-cli/1.2.3", "device": { "id": "device_fingerprint", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" } } }

    Gateway → Client:

    json
    { "type": "res", "id": "…", "ok": true, "payload": { "type": "hello-ok", "protocol": 3, "server": { "version": "…", "connId": "…" }, "features": { "methods": ["…"], "events": ["…"] }, "snapshot": { "…": "…" }, "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] }, "policy": { "maxPayload": 26214400, "maxBufferedBytes": 52428800, "tickIntervalMs": 15000 } } }

    While the Gateway is still finishing startup sidecars, the

    text
    connect
    request can return a retryable
    text
    UNAVAILABLE
    error with
    text
    details.reason
    set to
    text
    "startup-sidecars"
    and
    text
    retryAfterMs
    . Clients should retry that response within their overall connection budget instead of surfacing it as a terminal handshake failure.

    text
    server
    ,
    text
    features
    ,
    text
    snapshot
    , and
    text
    policy
    are all required by the schema (
    text
    src/gateway/protocol/schema/frames.ts
    ).
    text
    auth
    is also required and reports the negotiated role/scopes.
    text
    canvasHostUrl
    is optional.

    When no device token is issued,

    text
    hello-ok.auth
    reports the negotiated permissions without token fields:

    json
    { "auth": { "role": "operator", "scopes": ["operator.read", "operator.write"] } }

    Trusted same-process backend clients (

    text
    client.id: "gateway-client"
    ,
    text
    client.mode: "backend"
    ) may omit
    text
    device
    on direct loopback connections when they authenticate with the shared gateway token/password. This path is reserved for internal control-plane RPCs and keeps stale CLI/device pairing baselines from blocking local backend work such as subagent session updates. Remote clients, browser-origin clients, node clients, and explicit device-token/device-identity clients still use the normal pairing and scope-upgrade checks.

    When a device token is issued,

    text
    hello-ok
    also includes:

    json
    { "auth": { "deviceToken": "…", "role": "operator", "scopes": ["operator.read", "operator.write"] } }

    During trusted bootstrap handoff,

    text
    hello-ok.auth
    may also include additional bounded role entries in
    text
    deviceTokens
    :

    json
    { "auth": { "deviceToken": "…", "role": "node", "scopes": [], "deviceTokens": [ { "deviceToken": "…", "role": "operator", "scopes": ["operator.approvals", "operator.read", "operator.talk.secrets", "operator.write"] } ] } }

    For the built-in node/operator bootstrap flow, the primary node token stays

    text
    scopes: []
    and any handed-off operator token stays bounded to the bootstrap operator allowlist (
    text
    operator.approvals
    ,
    text
    operator.read
    ,
    text
    operator.talk.secrets
    ,
    text
    operator.write
    ). Bootstrap scope checks stay role-prefixed: operator entries only satisfy operator requests, and non-operator roles still need scopes under their own role prefix.

    Node example

    json
    { "type": "req", "id": "…", "method": "connect", "params": { "minProtocol": 3, "maxProtocol": 3, "client": { "id": "ios-node", "version": "1.2.3", "platform": "ios", "mode": "node" }, "role": "node", "scopes": [], "caps": ["camera", "canvas", "screen", "location", "voice"], "commands": ["camera.snap", "canvas.navigate", "screen.record", "location.get"], "permissions": { "camera.capture": true, "screen.record": false }, "auth": { "token": "…" }, "locale": "en-US", "userAgent": "openclaw-ios/1.2.3", "device": { "id": "device_fingerprint", "publicKey": "…", "signature": "…", "signedAt": 1737264000000, "nonce": "…" } } }

    Framing

    • Request:
      text
      {type:"req", id, method, params}
    • Response:
      text
      {type:"res", id, ok, payload|error}
    • Event:
      text
      {type:"event", event, payload, seq?, stateVersion?}

    Side-effecting methods require idempotency keys (see schema).

    Roles + scopes

    Roles

    • text
      operator
      = control plane client (CLI/UI/automation).
    • text
      node
      = capability host (camera/screen/canvas/system.run).

    Scopes (operator)

    Common scopes:

    • text
      operator.read
    • text
      operator.write
    • text
      operator.admin
    • text
      operator.approvals
    • text
      operator.pairing
    • text
      operator.talk.secrets

    text
    talk.config
    with
    text
    includeSecrets: true
    requires
    text
    operator.talk.secrets
    (or
    text
    operator.admin
    ).

    Plugin-registered gateway RPC methods may request their own operator scope, but reserved core admin prefixes (

    text
    config.*
    ,
    text
    exec.approvals.*
    ,
    text
    wizard.*
    ,
    text
    update.*
    ) always resolve to
    text
    operator.admin
    .

    Method scope is only the first gate. Some slash commands reached through

    text
    chat.send
    apply stricter command-level checks on top. For example, persistent
    text
    /config set
    and
    text
    /config unset
    writes require
    text
    operator.admin
    .

    text
    node.pair.approve
    also has an extra approval-time scope check on top of the base method scope:

    • commandless requests:
      text
      operator.pairing
    • requests with non-exec node commands:
      text
      operator.pairing
      +
      text
      operator.write
    • requests that include
      text
      system.run
      ,
      text
      system.run.prepare
      , or
      text
      system.which
      :
      text
      operator.pairing
      +
      text
      operator.admin

    Caps/commands/permissions (node)

    Nodes declare capability claims at connect time:

    • text
      caps
      : high-level capability categories.
    • text
      commands
      : command allowlist for invoke.
    • text
      permissions
      : granular toggles (e.g.
      text
      screen.record
      ,
      text
      camera.capture
      ).

    The Gateway treats these as claims and enforces server-side allowlists.

    Presence

    • text
      system-presence
      returns entries keyed by device identity.
    • Presence entries include
      text
      deviceId
      ,
      text
      roles
      , and
      text
      scopes
      so UIs can show a single row per device even when it connects as both operator and node.
    • text
      node.list
      includes optional
      text
      lastSeenAtMs
      and
      text
      lastSeenReason
      fields. Connected nodes report their current connection time as
      text
      lastSeenAtMs
      with reason
      text
      connect
      ; paired nodes can also report durable background presence when a trusted node event updates their pairing metadata.

    Node background alive event

    Nodes may call

    text
    node.event
    with
    text
    event: "node.presence.alive"
    to record that a paired node was alive during a background wake without marking it connected.

    json
    { "event": "node.presence.alive", "payloadJSON": "{\"trigger\":\"silent_push\",\"sentAtMs\":1737264000000,\"displayName\":\"Peter's iPhone\",\"version\":\"2026.4.28\",\"platform\":\"iOS 18.4.0\",\"deviceFamily\":\"iPhone\",\"modelIdentifier\":\"iPhone17,1\",\"pushTransport\":\"relay\"}" }

    text
    trigger
    is a closed enum:
    text
    background
    ,
    text
    silent_push
    ,
    text
    bg_app_refresh
    ,
    text
    significant_location
    ,
    text
    manual
    , or
    text
    connect
    . Unknown trigger strings are normalized to
    text
    background
    by the gateway before persistence. The event is durable only for authenticated node device sessions; device-less or unpaired sessions return
    text
    handled: false
    .

    Successful gateways return a structured result:

    json
    { "ok": true, "event": "node.presence.alive", "handled": true, "reason": "persisted" }

    Older gateways may still return

    text
    { "ok": true }
    for
    text
    node.event
    ; clients should treat that as an acknowledged RPC, not as durable presence persistence.

    Broadcast event scoping

    Server-pushed WebSocket broadcast events are scope-gated so that pairing-scoped or node-only sessions do not passively receive session content.

    • Chat, agent, and tool-result frames (including streamed
      text
      agent
      events and tool call results) require at least
      text
      operator.read
      . Sessions without
      text
      operator.read
      skip these frames entirely.
    • Plugin-defined
      text
      plugin.*
      broadcasts
      are gated to
      text
      operator.write
      or
      text
      operator.admin
      , depending on how the plugin registered them.
    • Status and transport events (
      text
      heartbeat
      ,
      text
      presence
      ,
      text
      tick
      , connect/disconnect lifecycle, etc.) remain unrestricted so transport health stays observable to every authenticated session.
    • Unknown broadcast event families are scope-gated by default (fail-closed) unless a registered handler explicitly relaxes them.

    Each client connection keeps its own per-client sequence number so broadcasts preserve monotonic ordering on that socket even when different clients see different scope-filtered subsets of the event stream.

    Common RPC method families

    The public WS surface is broader than the handshake/auth examples above. This is not a generated dump —

    text
    hello-ok.features.methods
    is a conservative discovery list built from
    text
    src/gateway/server-methods-list.ts
    plus loaded plugin/channel method exports. Treat it as feature discovery, not a full enumeration of
    text
    src/gateway/server-methods/*.ts
    .

    Common event families

    • text
      chat
      : UI chat updates such as
      text
      chat.inject
      and other transcript-only chat events.
    • text
      session.message
      and
      text
      session.tool
      : transcript/event-stream updates for a subscribed session.
    • text
      sessions.changed
      : session index or metadata changed.
    • text
      presence
      : system presence snapshot updates.
    • text
      tick
      : periodic keepalive / liveness event.
    • text
      health
      : gateway health snapshot update.
    • text
      heartbeat
      : heartbeat event stream update.
    • text
      cron
      : cron run/job change event.
    • text
      shutdown
      : gateway shutdown notification.
    • text
      node.pair.requested
      /
      text
      node.pair.resolved
      : node pairing lifecycle.
    • text
      node.invoke.request
      : node invoke request broadcast.
    • text
      device.pair.requested
      /
      text
      device.pair.resolved
      : paired-device lifecycle.
    • text
      voicewake.changed
      : wake-word trigger config changed.
    • text
      exec.approval.requested
      /
      text
      exec.approval.resolved
      : exec approval lifecycle.
    • text
      plugin.approval.requested
      /
      text
      plugin.approval.resolved
      : plugin approval lifecycle.

    Node helper methods

    • Nodes may call
      text
      skills.bins
      to fetch the current list of skill executables for auto-allow checks.

    Operator helper methods

    • Operators may call
      text
      commands.list
      (
      text
      operator.read
      ) to fetch the runtime command inventory for an agent.
      • text
        agentId
        is optional; omit it to read the default agent workspace.
      • text
        scope
        controls which surface the primary
        text
        name
        targets:
        • text
          text
          returns the primary text command token without the leading
          text
          /
        • text
          native
          and the default
          text
          both
          path return provider-aware native names when available
      • text
        textAliases
        carries exact slash aliases such as
        text
        /model
        and
        text
        /m
        .
      • text
        nativeName
        carries the provider-aware native command name when one exists.
      • text
        provider
        is optional and only affects native naming plus native plugin command availability.
      • text
        includeArgs=false
        omits serialized argument metadata from the response.
    • Operators may call
      text
      tools.catalog
      (
      text
      operator.read
      ) to fetch the runtime tool catalog for an agent. The response includes grouped tools and provenance metadata:
      • text
        source
        :
        text
        core
        or
        text
        plugin
      • text
        pluginId
        : plugin owner when
        text
        source="plugin"
      • text
        optional
        : whether a plugin tool is optional
    • Operators may call
      text
      tools.effective
      (
      text
      operator.read
      ) to fetch the runtime-effective tool inventory for a session.
      • text
        sessionKey
        is required.
      • The gateway derives trusted runtime context from the session server-side instead of accepting caller-supplied auth or delivery context.
      • The response is session-scoped and reflects what the active conversation can use right now, including core, plugin, and channel tools.
    • Operators may call
      text
      skills.status
      (
      text
      operator.read
      ) to fetch the visible skill inventory for an agent.
      • text
        agentId
        is optional; omit it to read the default agent workspace.
      • The response includes eligibility, missing requirements, config checks, and sanitized install options without exposing raw secret values.
    • Operators may call
      text
      skills.search
      and
      text
      skills.detail
      (
      text
      operator.read
      ) for ClawHub discovery metadata.
    • Operators may call
      text
      skills.install
      (
      text
      operator.admin
      ) in two modes:
      • ClawHub mode:
        text
        { source: "clawhub", slug, version?, force? }
        installs a skill folder into the default agent workspace
        text
        skills/
        directory.
      • Gateway installer mode:
        text
        { name, installId, dangerouslyForceUnsafeInstall?, timeoutMs? }
        runs a declared
        text
        metadata.openclaw.install
        action on the gateway host.
    • Operators may call
      text
      skills.update
      (
      text
      operator.admin
      ) in two modes:
      • ClawHub mode updates one tracked slug or all tracked ClawHub installs in the default agent workspace.
      • Config mode patches
        text
        skills.entries.<skillKey>
        values such as
        text
        enabled
        ,
        text
        apiKey
        , and
        text
        env
        .

    text
    models.list
    views

    text
    models.list
    accepts an optional
    text
    view
    parameter:

    • Omitted or
      text
      "default"
      : current runtime behavior. If
      text
      agents.defaults.models
      is configured, the response is the allowed catalog; otherwise the response is the full Gateway catalog.
    • text
      "configured"
      : picker-sized behavior. If
      text
      agents.defaults.models
      is configured, it still wins. Otherwise the response uses explicit
      text
      models.providers.*.models
      entries, falling back to the full catalog only when no configured model rows exist.
    • text
      "all"
      : full Gateway catalog, bypassing
      text
      agents.defaults.models
      . Use this for diagnostics and discovery UIs, not normal model pickers.

    Exec approvals

    • When an exec request needs approval, the gateway broadcasts
      text
      exec.approval.requested
      .
    • Operator clients resolve by calling
      text
      exec.approval.resolve
      (requires
      text
      operator.approvals
      scope).
    • For
      text
      host=node
      ,
      text
      exec.approval.request
      must include
      text
      systemRunPlan
      (canonical
      text
      argv
      /
      text
      cwd
      /
      text
      rawCommand
      /session metadata). Requests missing
      text
      systemRunPlan
      are rejected.
    • After approval, forwarded
      text
      node.invoke system.run
      calls reuse that canonical
      text
      systemRunPlan
      as the authoritative command/cwd/session context.
    • If a caller mutates
      text
      command
      ,
      text
      rawCommand
      ,
      text
      cwd
      ,
      text
      agentId
      , or
      text
      sessionKey
      between prepare and the final approved
      text
      system.run
      forward, the gateway rejects the run instead of trusting the mutated payload.

    Agent delivery fallback

    • text
      agent
      requests can include
      text
      deliver=true
      to request outbound delivery.
    • text
      bestEffortDeliver=false
      keeps strict behavior: unresolved or internal-only delivery targets return
      text
      INVALID_REQUEST
      .
    • text
      bestEffortDeliver=true
      allows fallback to session-only execution when no external deliverable route can be resolved (for example internal/webchat sessions or ambiguous multi-channel configs).

    Versioning

    • text
      PROTOCOL_VERSION
      lives in
      text
      src/gateway/protocol/schema/protocol-schemas.ts
      .
    • Clients send
      text
      minProtocol
      +
      text
      maxProtocol
      ; the server rejects mismatches.
    • Schemas + models are generated from TypeBox definitions:
      • text
        pnpm protocol:gen
      • text
        pnpm protocol:gen:swift
      • text
        pnpm protocol:check

    Client constants

    The reference client in

    text
    src/gateway/client.ts
    uses these defaults. Values are stable across protocol v3 and are the expected baseline for third-party clients.

    ConstantDefaultSource
    text
    PROTOCOL_VERSION
    text
    3
    text
    src/gateway/protocol/schema/protocol-schemas.ts
    Request timeout (per RPC)
    text
    30_000
    ms
    text
    src/gateway/client.ts
    (
    text
    requestTimeoutMs
    )
    Preauth / connect-challenge timeout
    text
    15_000
    ms
    text
    src/gateway/handshake-timeouts.ts
    (config/env can raise the paired server/client budget)
    Initial reconnect backoff
    text
    1_000
    ms
    text
    src/gateway/client.ts
    (
    text
    backoffMs
    )
    Max reconnect backoff
    text
    30_000
    ms
    text
    src/gateway/client.ts
    (
    text
    scheduleReconnect
    )
    Fast-retry clamp after device-token close
    text
    250
    ms
    text
    src/gateway/client.ts
    Force-stop grace before
    text
    terminate()
    text
    250
    ms
    text
    FORCE_STOP_TERMINATE_GRACE_MS
    text
    stopAndWait()
    default timeout
    text
    1_000
    ms
    text
    STOP_AND_WAIT_TIMEOUT_MS
    Default tick interval (pre
    text
    hello-ok
    )
    text
    30_000
    ms
    text
    src/gateway/client.ts
    Tick-timeout closecode
    text
    4000
    when silence exceeds
    text
    tickIntervalMs * 2
    text
    src/gateway/client.ts
    text
    MAX_PAYLOAD_BYTES
    text
    25 * 1024 * 1024
    (25 MB)
    text
    src/gateway/server-constants.ts

    The server advertises the effective

    text
    policy.tickIntervalMs
    ,
    text
    policy.maxPayload
    , and
    text
    policy.maxBufferedBytes
    in
    text
    hello-ok
    ; clients should honor those values rather than the pre-handshake defaults.

    Auth

    • Shared-secret gateway auth uses
      text
      connect.params.auth.token
      or
      text
      connect.params.auth.password
      , depending on the configured auth mode.
    • Identity-bearing modes such as Tailscale Serve (
      text
      gateway.auth.allowTailscale: true
      ) or non-loopback
      text
      gateway.auth.mode: "trusted-proxy"
      satisfy the connect auth check from request headers instead of
      text
      connect.params.auth.*
      .
    • Private-ingress
      text
      gateway.auth.mode: "none"
      skips shared-secret connect auth entirely; do not expose that mode on public/untrusted ingress.
    • After pairing, the Gateway issues a device token scoped to the connection role + scopes. It is returned in
      text
      hello-ok.auth.deviceToken
      and should be persisted by the client for future connects.
    • Clients should persist the primary
      text
      hello-ok.auth.deviceToken
      after any successful connect.
    • Reconnecting with that stored device token should also reuse the stored approved scope set for that token. This preserves read/probe/status access that was already granted and avoids silently collapsing reconnects to a narrower implicit admin-only scope.
    • Client-side connect auth assembly (
      text
      selectConnectAuth
      in
      text
      src/gateway/client.ts
      ):
      • text
        auth.password
        is orthogonal and is always forwarded when set.
      • text
        auth.token
        is populated in priority order: explicit shared token first, then an explicit
        text
        deviceToken
        , then a stored per-device token (keyed by
        text
        deviceId
        +
        text
        role
        ).
      • text
        auth.bootstrapToken
        is sent only when none of the above resolved an
        text
        auth.token
        . A shared token or any resolved device token suppresses it.
      • Auto-promotion of a stored device token on the one-shot
        text
        AUTH_TOKEN_MISMATCH
        retry is gated to trusted endpoints only — loopback, or
        text
        wss://
        with a pinned
        text
        tlsFingerprint
        . Public
        text
        wss://
        without pinning does not qualify.
    • Additional
      text
      hello-ok.auth.deviceTokens
      entries are bootstrap handoff tokens. Persist them only when the connect used bootstrap auth on a trusted transport such as
      text
      wss://
      or loopback/local pairing.
    • If a client supplies an explicit
      text
      deviceToken
      or explicit
      text
      scopes
      , that caller-requested scope set remains authoritative; cached scopes are only reused when the client is reusing the stored per-device token.
    • Device tokens can be rotated/revoked via
      text
      device.token.rotate
      and
      text
      device.token.revoke
      (requires
      text
      operator.pairing
      scope).
    • text
      device.token.rotate
      returns rotation metadata. It echoes the replacement bearer token only for same-device calls that are already authenticated with that device token, so token-only clients can persist their replacement before reconnecting. Shared/admin rotations do not echo the bearer token.
    • Token issuance, rotation, and revocation stay bounded to the approved role set recorded in that device's pairing entry; token mutation cannot expand or target a device role that pairing approval never granted.
    • For paired-device token sessions, device management is self-scoped unless the caller also has
      text
      operator.admin
      : non-admin callers can remove/revoke/rotate only their own device entry.
    • text
      device.token.rotate
      and
      text
      device.token.revoke
      also check the target operator token scope set against the caller's current session scopes. Non-admin callers cannot rotate or revoke a broader operator token than they already hold.
    • Auth failures include
      text
      error.details.code
      plus recovery hints:
      • text
        error.details.canRetryWithDeviceToken
        (boolean)
      • text
        error.details.recommendedNextStep
        (
        text
        retry_with_device_token
        ,
        text
        update_auth_configuration
        ,
        text
        update_auth_credentials
        ,
        text
        wait_then_retry
        ,
        text
        review_auth_configuration
        )
    • Client behavior for
      text
      AUTH_TOKEN_MISMATCH
      :
      • Trusted clients may attempt one bounded retry with a cached per-device token.
      • If that retry fails, clients should stop automatic reconnect loops and surface operator action guidance.

    Device identity + pairing

    • Nodes should include a stable device identity (
      text
      device.id
      ) derived from a keypair fingerprint.
    • Gateways issue tokens per device + role.
    • Pairing approvals are required for new device IDs unless local auto-approval is enabled.
    • Pairing auto-approval is centered on direct local loopback connects.
    • OpenClaw also has a narrow backend/container-local self-connect path for trusted shared-secret helper flows.
    • Same-host tailnet or LAN connects are still treated as remote for pairing and require approval.
    • WS clients normally include
      text
      device
      identity during
      text
      connect
      (operator + node). The only device-less operator exceptions are explicit trust paths:
      • text
        gateway.controlUi.allowInsecureAuth=true
        for localhost-only insecure HTTP compatibility.
      • successful
        text
        gateway.auth.mode: "trusted-proxy"
        operator Control UI auth.
      • text
        gateway.controlUi.dangerouslyDisableDeviceAuth=true
        (break-glass, severe security downgrade).
      • direct-loopback
        text
        gateway-client
        backend RPCs authenticated with the shared gateway token/password.
    • All connections must sign the server-provided
      text
      connect.challenge
      nonce.

    Device auth migration diagnostics

    For legacy clients that still use pre-challenge signing behavior,

    text
    connect
    now returns
    text
    DEVICE_AUTH_*
    detail codes under
    text
    error.details.code
    with a stable
    text
    error.details.reason
    .

    Common migration failures:

    Messagedetails.codedetails.reasonMeaning
    text
    device nonce required
    text
    DEVICE_AUTH_NONCE_REQUIRED
    text
    device-nonce-missing
    Client omitted
    text
    device.nonce
    (or sent blank).
    text
    device nonce mismatch
    text
    DEVICE_AUTH_NONCE_MISMATCH
    text
    device-nonce-mismatch
    Client signed with a stale/wrong nonce.
    text
    device signature invalid
    text
    DEVICE_AUTH_SIGNATURE_INVALID
    text
    device-signature
    Signature payload does not match v2 payload.
    text
    device signature expired
    text
    DEVICE_AUTH_SIGNATURE_EXPIRED
    text
    device-signature-stale
    Signed timestamp is outside allowed skew.
    text
    device identity mismatch
    text
    DEVICE_AUTH_DEVICE_ID_MISMATCH
    text
    device-id-mismatch
    text
    device.id
    does not match public key fingerprint.
    text
    device public key invalid
    text
    DEVICE_AUTH_PUBLIC_KEY_INVALID
    text
    device-public-key
    Public key format/canonicalization failed.

    Migration target:

    • Always wait for
      text
      connect.challenge
      .
    • Sign the v2 payload that includes the server nonce.
    • Send the same nonce in
      text
      connect.params.device.nonce
      .
    • Preferred signature payload is
      text
      v3
      , which binds
      text
      platform
      and
      text
      deviceFamily
      in addition to device/client/role/scopes/token/nonce fields.
    • Legacy
      text
      v2
      signatures remain accepted for compatibility, but paired-device metadata pinning still controls command policy on reconnect.

    TLS + pinning

    • TLS is supported for WS connections.
    • Clients may optionally pin the gateway cert fingerprint (see
      text
      gateway.tls
      config plus
      text
      gateway.remote.tlsFingerprint
      or CLI
      text
      --tls-fingerprint
      ).

    Scope

    This protocol exposes the full gateway API (status, channels, models, chat, agent, sessions, nodes, approvals, etc.). The exact surface is defined by the TypeBox schemas in

    text
    src/gateway/protocol/schema.ts
    .

    Related

    • Bridge protocol
    • Gateway runbook

    © 2024 TaskFlow Mirror

    Powered by TaskFlow Sync Engine