fix: harden pairing flow

This commit is contained in:
Peter Steinberger
2026-01-07 05:06:04 +01:00
parent 6ffece68b0
commit 42ae2341aa
22 changed files with 679 additions and 265 deletions

View File

@@ -195,6 +195,8 @@ Controls how WhatsApp direct chats (DMs) are handled:
- `"open"`: allow all inbound DMs (**requires** `whatsapp.allowFrom` to include `"*"`)
- `"disabled"`: ignore all inbound DMs
Pairing codes expire after 1 hour; the bot only sends a pairing code when a new request is created.
Pairing approvals:
- `clawdbot pairing list --provider whatsapp`
- `clawdbot pairing approve --provider whatsapp <code>`

View File

@@ -38,7 +38,7 @@ Clawdbots stance:
All current DM-capable providers support a DM policy (`dmPolicy` or `*.dm.policy`) that gates inbound DMs **before** the message is processed:
- `pairing` (default): unknown senders receive a short pairing code and the bot ignores their message until approved.
- `pairing` (default): unknown senders receive a short pairing code and the bot ignores their message until approved. Codes expire after 1 hour; repeated DMs wont resend a code until a new request is created.
- `allowlist`: unknown senders are blocked (no pairing handshake).
- `open`: allow anyone to DM (public). **Requires** the provider allowlist to include `"*"` (explicit opt-in).
- `disabled`: ignore inbound DMs entirely.

View File

@@ -23,7 +23,7 @@ Status: ready for DM and guild text channels via the official Discord bot gatewa
- If you prefer env vars, still add `discord: { enabled: true }` to `~/.clawdbot/clawdbot.json` and set `DISCORD_BOT_TOKEN`.
5. Direct chats: use `user:<id>` (or a `<@id>` mention) when delivering; all turns land in the shared `main` session.
6. Guild channels: use `channel:<channelId>` for delivery. Mentions are required by default and can be set per guild or per channel.
7. Direct chats: secure by default via `discord.dm.policy` (default: `"pairing"`). Unknown senders get a pairing code; approve via `clawdbot pairing approve --provider discord <code>`.
7. Direct chats: secure by default via `discord.dm.policy` (default: `"pairing"`). Unknown senders get a pairing code (expires after 1 hour); approve via `clawdbot pairing approve --provider discord <code>`.
- To keep old “open to anyone” behavior: set `discord.dm.policy="open"` and `discord.dm.allowFrom=["*"]`.
- To hard-allowlist: set `discord.dm.policy="allowlist"` and list senders in `discord.dm.allowFrom`.
- To ignore all DMs: set `discord.dm.enabled=false` or `discord.dm.policy="disabled"`.

View File

@@ -39,7 +39,7 @@ Example:
## Access control (DMs + groups)
DMs:
- Default: `imessage.dmPolicy = "pairing"`.
- Unknown senders receive a pairing code; messages are ignored until approved.
- Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).
- Approve via:
- `clawdbot pairing list --provider imessage`
- `clawdbot pairing approve --provider imessage <CODE>`

View File

@@ -42,7 +42,7 @@ Example:
## Access control (DMs + groups)
DMs:
- Default: `signal.dmPolicy = "pairing"`.
- Unknown senders receive a pairing code; messages are ignored until approved.
- Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).
- Approve via:
- `clawdbot pairing list --provider signal`
- `clawdbot pairing approve --provider signal <CODE>`

View File

@@ -195,7 +195,7 @@ Ack reactions are controlled globally via `messages.ackReaction` +
- Full command list + config: [Slash commands](/tools/slash-commands)
## DM security (pairing)
- Default: `slack.dm.policy="pairing"` — unknown DM senders get a pairing code.
- Default: `slack.dm.policy="pairing"` — unknown DM senders get a pairing code (expires after 1 hour).
- Approve via: `clawdbot pairing approve --provider slack <code>`.
- To allow anyone: set `slack.dm.policy="open"` and `slack.dm.allowFrom=["*"]`.

View File

@@ -45,7 +45,7 @@ Telegram forum topics include a `message_thread_id` per message. Clawdbot:
- Exposes `MessageThreadId` + `IsForum` in template context for routing/templating.
## Access control (DMs + groups)
- Default: `telegram.dmPolicy = "pairing"`. Unknown senders receive a pairing code; messages are ignored until approved.
- Default: `telegram.dmPolicy = "pairing"`. Unknown senders receive a pairing code; messages are ignored until approved (codes expire after 1 hour).
- Approve via:
- `clawdbot pairing list --provider telegram`
- `clawdbot pairing approve --provider telegram <CODE>`

View File

@@ -51,7 +51,7 @@ WhatsApp requires a real mobile number for verification. VoIP and virtual number
- Status/broadcast chats are ignored.
- Direct chats use E.164; groups use group JID.
- **DM policy**: `whatsapp.dmPolicy` controls direct chat access (default: `pairing`).
- Pairing: unknown senders get a pairing code (approve via `clawdbot pairing approve --provider whatsapp <code>`).
- Pairing: unknown senders get a pairing code (approve via `clawdbot pairing approve --provider whatsapp <code>`; codes expire after 1 hour).
- Open: requires `whatsapp.allowFrom` to include `"*"`.
- Self messages are always allowed; “self-chat mode” still requires `whatsapp.allowFrom` to include your own number.
- **Group policy**: `whatsapp.groupPolicy` controls group handling (`open|disabled|allowlist`).

View File

@@ -22,6 +22,10 @@ When a provider is configured with DM policy `pairing`, unknown senders get a sh
Default DM policies are documented in: [Security](/gateway/security)
Pairing codes:
- 8 characters, uppercase, no ambiguous chars (`0O1I`).
- **Expire after 1 hour**. The bot only sends the pairing message when a new request is created (roughly once per hour per sender).
### Approve a sender
```bash