Skip to content

WhatsApp type=acp configured binding is not materialized; turns fall back to local embedded execution #92449

Description

@dmorn

Title

WhatsApp type: "acp" configured binding is not materialized; turns fall back to local embedded execution

Severity Assessment

Medium to High, depending on deployment model. This is a security-relevant misrouting / sandbox-boundary issue: a WhatsApp conversation can appear to be assigned to an agent configured for a remote ACP runtime, while the actual turn executes through the gateway host's local embedded runtime.

Impact

For multi-agent or multi-tenant deployments where each agent is intended to run in its own ACP backend or remote VM, a WhatsApp direct conversation matching a type: "acp" binding may silently execute on the gateway host instead of the configured ACP backend.

The operator sees the intended agent id selected, but the ACP binding is not materialized and there is no obvious runtime error. This can bypass the expected per-agent VM/sandbox isolation.

This is related to #75211, but the observed failure here is specifically ACP configured binding materialization. In the observed setup, WhatsApp did resolve the direct peer to the configured agent; the failure was that the selected agent's configured ACP binding was not used for execution.

Affected Component

  • OpenClaw 2026.6.5
  • @openclaw/whatsapp 2026.6.5
  • WhatsApp channel plugin configured bindings
  • ACP/acpx configured binding lifecycle

Technical Reproduction

Sanitized config shape:

{
  "acp": {
    "enabled": true,
    "backend": "acpx"
  },
  "plugins": {
    "entries": {
      "acpx": { "enabled": true },
      "codex": { "enabled": false }
    }
  },
  "agents": {
    "list": [
      {
        "id": "sandboxed-agent",
        "runtime": {
          "type": "acp",
          "acp": {
            "agent": "codex",
            "cwd": "/home/user/agent-workspace",
            "mode": "oneshot"
          }
        }
      }
    ]
  },
  "bindings": [
    {
      "type": "acp",
      "agentId": "sandboxed-agent",
      "match": {
        "channel": "whatsapp",
        "accountId": "<redacted-account>",
        "peer": {
          "kind": "direct",
          "id": "<redacted-direct-peer>"
        }
      }
    }
  ]
}

Steps:

  1. Configure WhatsApp and ACP/acpx as above.
  2. Send a direct WhatsApp message from the matching peer.
  3. Ask the agent to run a simple environment-revealing command, for example hostname.
  4. Inspect the OpenClaw session key and ACP/Codex session artifacts.

Observed:

  • WhatsApp resolves the direct peer to sandboxed-agent.
  • The active session key remains the normal local route shape:
agent:sandboxed-agent:whatsapp:direct:<redacted-direct-peer>
  • It does not become a configured ACP binding session key:
agent:sandboxed-agent:acp:binding:whatsapp:<redacted-account>:<hash>
  • The tool call executes on the gateway host.
  • No new remote ACP/Codex session artifact appears on the configured remote ACP backend.

A direct runtime probe against the same config also returns no configured binding:

resolveConfiguredAcpBindingRecord({
  cfg,
  channel: "whatsapp",
  accountId: "<redacted-account>",
  conversationId: "<redacted-direct-peer>"
})
// => null

Demonstrated Impact

The failure is silent. The gateway selects the intended configured agent id, but because the WhatsApp ACP configured binding is not materialized, dispatch falls back to local embedded execution.

In the observed run, the session artifact showed local gateway-host execution and the command result identified the gateway host, while the expected remote ACP backend produced no new ACP/Codex session artifact.

This creates a sandbox/isolation footgun for deployments where the gateway is only intended to route messages and each agent is expected to execute in a separate ACP backend.

Expected Behavior

A WhatsApp conversation matching a type: "acp" binding should either:

  1. Materialize the configured ACP binding and initialize/use the ACP session, producing a session key like:
agent:sandboxed-agent:acp:binding:whatsapp:<redacted-account>:<hash>
  1. Fail loudly with a clear error indicating that WhatsApp does not support configured ACP bindings.

It should not silently continue through the gateway host's embedded runtime.

Suspected Root Cause

The current WhatsApp channel plugin appears not to expose the configured-binding adapter fields required by the core binding registry:

  • bindings.compileConfiguredBinding
  • bindings.matchInboundConversation

Other channel plugins expose these fields. Core configured binding resolution requires them; without them, the configured binding is not compiled/materialized and resolveConfiguredAcpBindingRecord(...) returns null.

Separately, normal resolveAgentRoute(...) only considers type: "route" bindings. That is expected for ordinary routing, but it means type: "acp" ownership must be materialized through the configured-binding path before dispatch.

Remediation Advice

Add WhatsApp configured-binding support equivalent to the other channel plugins:

  1. Add a WhatsApp bindings adapter with compileConfiguredBinding and matchInboundConversation.
  2. Support direct peer conversations at minimum; group/channel matching can be added consistently with existing WhatsApp peer normalization.
  3. Ensure the WhatsApp inbound path materializes/ensures configured ACP bindings before dispatch, using the existing configured ACP binding lifecycle.
  4. Add a regression test for bindings[].type = "acp" on WhatsApp direct messages:
    • matching peer resolves to the configured agent,
    • configured ACP session key is used,
    • embedded local execution is not used.
  5. If WhatsApp configured ACP bindings are intentionally unsupported, emit a validation or startup warning/error for bindings[].match.channel === "whatsapp" with type: "acp".

Environment

  • OpenClaw: 2026.6.5
  • WhatsApp plugin: @openclaw/whatsapp 2026.6.5
  • ACP backend: acpx
  • Channel: WhatsApp direct message
  • Platform: Linux gateway host

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions