openclaw - 💡(How to fix) Fix [Feature]: Per-sender inbound DM rate limit for channel pairing/allowlist policies [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Add a per-sender rate limit (requests-per-window) to inbound DMs on auth-sensitive channel policies (channels.<chan>.dmPolicy = pairing or allowlist), independent of the global messages.queue.cap.

Error Message

  • channels.telegram.errorCooldownMs triggers only on error paths, not on inbound traffic. Summary: 0 critical · 0 warn · 1 info

Root Cause

Add a per-sender rate limit (requests-per-window) to inbound DMs on auth-sensitive channel policies (channels.<chan>.dmPolicy = pairing or allowlist), independent of the global messages.queue.cap.

Fix Action

Fixed

Code Example

channels:
  telegram:
    rateLimit:
      perSender:
        windowSeconds: 60
        maxRequests: 5         # inbound DMs from one sender ID
        dropPolicy: silent     # silent | errorReply | summary
      pairing:
        windowSeconds: 3600
        maxRequests: 3         # pairing attempts per sender per hour
        backoffMs: 60000       # exponential backoff after limit
      exemptSenderIds:         # bypass for owners / allowFrom
        - "telegram:1234567890"

---

Summary: 0 critical · 0 warn · 1 info
  INFO summary.attack_surface
    trust model: personal assistant (one trusted operator boundary)
RAW_BUFFERClick to expand / collapse

Summary

Add a per-sender rate limit (requests-per-window) to inbound DMs on auth-sensitive channel policies (channels.<chan>.dmPolicy = pairing or allowlist), independent of the global messages.queue.cap.

Problem to solve

With channels.telegram.dmPolicy = "pairing" (or "allowlist"), any Telegram account that knows the bot's @handle can submit a pairing request and land in the inbound queue. There is no per-sender throttle:

  • A single hostile sender can flood the inbound queue with pairing requests.
  • messages.queue.cap (default 20) bounds memory but only at the global level — it cannot distinguish per-sender traffic.
  • messages.queue.drop = "summarize" preserves audit stubs, but spam still consumes summary slots and evicts legitimate-traffic summaries under sustained flood (see queue-*.js summaryLimit shift behavior).
  • The owner sees noise in the pairing queue and pays the summary-token cost.

I walked the config schema looking for an existing knob and could not find one:

  • openclaw config schema exposes no channels.telegram.rateLimit*, no pairing.rateLimit*, no commands.rateLimit*.
  • gateway.nodes.pairing exists but governs node-host pairing (CIDR auto-approval), not channel DM throttling.
  • channels.telegram.errorCooldownMs triggers only on error paths, not on inbound traffic.
  • channels.telegram.retry is outbound (post-failure backoff), not inbound.

The security audit correctly summarizes the deployment as "personal assistant (one trusted operator boundary)" — but there is no enforcement for the non-operator inbound work surface, even when those senders never reach an approved/paired state.

Proposed solution

Add per-sender rate-limit knobs under each channel (and/or under commands for cross-channel defaults). Suggested config shape:

channels:
  telegram:
    rateLimit:
      perSender:
        windowSeconds: 60
        maxRequests: 5         # inbound DMs from one sender ID
        dropPolicy: silent     # silent | errorReply | summary
      pairing:
        windowSeconds: 3600
        maxRequests: 3         # pairing attempts per sender per hour
        backoffMs: 60000       # exponential backoff after limit
      exemptSenderIds:         # bypass for owners / allowFrom
        - "telegram:1234567890"

Behavior:

  • Counted before the message enters messages.queue (so spam never consumes the global cap).
  • Enforced at the channel adapter layer (Telegram / Discord / Signal / etc.).
  • Allowlist/owner senders bypass the limit, or get a higher limit, via exemptSenderIds.
  • A separate pairing counter bounds the pairing-queue-specific DoS independent of post-pairing DM rate.

Default: no limit set → identical to current behavior (backward compatible).

Alternatives considered

  • Lowering messages.queue.cap: still per-channel, not per-sender. Legitimate cron messages get dropped alongside spam.
  • dmPolicy = "disabled": defeats the purpose of allowing pairing-mode operation.
  • Custom plugin / shim: would require maintaining a fork or extension; not portable across openclaw upgrades.
  • External (nginx) rate limit on the Telegram webhook: only viable for webhook-mode deployments, not polling.

Impact

  • Affected: any deployment using dmPolicy = "pairing" or "allowlist" on Telegram (and any other channel where the same policy semantics apply).
  • Severity: Medium — enables a low-effort DoS / log-flood / summary-eviction attack against single-operator deployments.
  • Frequency: Currently rare (requires bot @handle disclosure), but inevitable for any production bot that publishes a handle or whose handle leaks via prior public interaction.
  • Consequence: Owner notifications drowned in spam summaries; operator must triage queue manually; in extreme cases, useful traffic is silently summary-evicted before reaching the model.

Evidence/examples

  • Schema check: openclaw config schema | grep -i -E "rateLimit|throttle" returns paths for outbound auth/provider cooldowns and TLS/proxy reliability — none for channel-inbound traffic.
  • Audit output on 2026.5.18 (gateway and channel both healthy, no warns):
    Summary: 0 critical · 0 warn · 1 info
    INFO summary.attack_surface
      trust model: personal assistant (one trusted operator boundary)
    The audit describes the trust model but does not flag the absence of an inbound rate-limit knob that would enforce it.
  • Related prior art in this repo (distinct surfaces, none of which solve channel-inbound per-sender throttling):
    • #77986 — gateway auth rate-limiter entries map lacks a hard cap under unique-IP flood
    • #77977/#77978/#77980 — pre-auth verify-path DoS surfaces
    • #13615 — rate limiting for external (outbound) API calls
    • #54798, #14376 — cron quota / rate-limit-aware backoff

Additional information

  • Version: openclaw 2026.5.18 (50a2481)
  • Platform: macOS 26.4.1 (arm64), node 22.19+
  • Trust model in use: single trusted operator, dmPolicy = "pairing", commands.ownerAllowFrom set
  • Backward compatibility: feature should default to "no limit" so existing deployments are unchanged unless they opt in
  • Adjacent cleanup that could ride along: channels.telegram.allowFrom is documented as an object in config schema but stored as an array on disk; clarifying the shape would reduce ambiguity for users setting per-sender exemption lists

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Feature]: Per-sender inbound DM rate limit for channel pairing/allowlist policies [1 pull requests]