- DM pairing (who is allowed to talk to the bot)
- Node pairing (which devices/nodes are allowed to join the gateway network)
1) DM pairing (inbound chat access)
When a channel is configured with DM policypairing, unknown senders get a short code and their message is not processed until you approve.
Default DM policies are documented in: Security
dmPolicy: "open" is public only when the effective DM allowlist includes "*".
Setup and validation require that wildcard for public-open configs. If existing
state contains open with concrete allowFrom entries, runtime still admits
only those senders, and pairing-store approvals do not widen open access.
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).
- Pending DM pairing requests are capped at 3 per channel account; additional requests are ignored until one expires or is approved.
Approve a sender
--notify to the approve command to tell the requester on the same channel. Multi-account channels take --account <id>.
If no command owner is configured yet, approving a DM pairing code also bootstraps
commands.ownerAllowFrom to the approved sender, such as telegram:123456789.
That gives first-time setups an explicit owner for privileged commands and exec
approval prompts. After an owner exists, later pairing approvals only grant DM
access; they do not add more owners.
Supported channels (any installed channel plugin that declares pairing; external plugins such as openclaw-weixin can add more): discord, feishu, googlechat, imessage, irc, line, matrix, mattermost, msteams, nextcloud-talk, nostr, signal, slack, sms, synology-chat, telegram, twitch, whatsapp, zalo, zalouser.
Reusable sender groups
Use top-levelaccessGroups when the same trusted sender set should apply to
multiple message channels or to both DM and group allowlists.
Static groups use type: "message.senders" and are referenced with
accessGroup:<name> from channel allowlists:
Where the state lives
Stored in the shared SQLite state database at~/.openclaw/state/openclaw.sqlite:
- pending requests in
channel_pairing_requests - approved senders in
channel_pairing_allow_entries
- each request and approved sender is keyed by channel and account
- runtime reads only the canonical SQLite rows; it does not merge legacy files
<channel>-pairing.json and
<channel>-<accountId>-allowFrom.json under ~/.openclaw/credentials/.
Startup migration and openclaw doctor --fix import those files into SQLite and
remove each source after a successful import. Treat the SQLite database as
sensitive because these rows gate access to your assistant.
The pairing allowlist store is for DM access. Group authorization is separate.
Approving a DM pairing code does not automatically allow that sender to run group
commands or control the bot in groups. First-owner bootstrap is separate config
state in
commands.ownerAllowFrom, and group chat delivery still follows the
channel’s group allowlists (for example groupAllowFrom, groups, or per-group
or per-topic overrides depending on the channel).2) Node device pairing (iOS/Android/macOS/headless nodes)
Nodes connect to the Gateway as devices withrole: node. The Gateway
creates a device pairing request that must be approved.
Pair from the Control UI (recommended)
Use an already connected Control UI session withoperator.admin access:
- Open the Control UI and go to Settings → Devices.
- On the Devices page, click Pair mobile device.
- Keep Full access (recommended), or select Limited access to omit administrative Gateway controls.
- Click Create setup code.
- On your phone, open the OpenClaw app → Settings → Gateway.
- Scan the QR code or paste the setup code, then connect.
Pair via Telegram
If you use thedevice-pair plugin, you can do first-time device pairing entirely from Telegram:
- In Telegram, message your bot:
/pair - The bot replies with two messages: an instruction message and a separate setup code message (easy to copy/paste in Telegram).
- On your phone, open the OpenClaw iOS app → Settings → Gateway.
- Scan the QR code (
/pair qr) or paste the setup code and connect. - The official mobile app connects automatically. If
/pair pendingshows a request, review its role and scopes before approving it.
url: the Gateway WebSocket URL (ws://...orwss://...)urls: when available, the ordered LAN/Tailnet routes the mobile app can trybootstrapToken: a single-use bootstrap token for the initial pairing handshake; the Gateway expires it after 10 minutes
/pair cleanup to invalidate unused setup codes once pairing finishes.
That bootstrap token carries the built-in pairing bootstrap profile:
- a secure
wss://setup (or same-host loopback) defaults tonodeplus full native-mobileoperatoraccess - the handed-off
nodetoken staysscopes: [] - the default handed-off
operatortoken includesoperator.admin,operator.approvals,operator.read,operator.talk.secrets, andoperator.write - Control UI Limited access and
openclaw qr --limitedomitoperator.adminwhile keeping the other operator scopes - plaintext LAN
ws://setup automatically uses the same limited profile; configurewss://or Tailscale Serve and generate a new code for full access - later token rotation/revocation remains bounded by both the device’s approved role contract and the caller session’s operator scopes
wss:// or
Tailscale Serve route, then generate a new full-access setup code, scan or paste
it in that settings page, and reconnect.
For Tailscale, public, or other remote mobile pairing, use Tailscale Serve/Funnel
or another wss:// Gateway URL. Plaintext ws:// setup codes are accepted only
for loopback, private LAN addresses, .local Bonjour hosts, and the Android
emulator host. Non-loopback plaintext routes receive limited access. Tailnet
CGNAT addresses, .ts.net names, and public hosts still fail closed before
QR/setup-code issuance.
For gateway.bind=lan setup URLs, OpenClaw detects persistent Tailscale Serve
HTTPS roots that proxy the active Gateway’s loopback port and advertises them
alongside the LAN route. The setup command adds this fallback only
for lan; custom and tailnet keep their explicitly advertised routes. The
iOS app probes the advertised routes in order and saves the first reachable
endpoint.
Approve a node device
operator.admin. This lets an existing admin-capable paired device recover a new
Control UI/browser pairing without editing the pairing store by hand. The
Gateway still validates the retried connection; tokens that cannot authenticate
with operator.admin remain blocked.
If the same device retries with different auth details (for example different
role/scopes/public key), the previous pending request is superseded and a new
requestId is created.
An already paired device does not get broader access silently. If it reconnects asking for more scopes or a broader role, OpenClaw keeps the existing approval as-is and creates a fresh pending upgrade request. Use
openclaw devices list to compare the currently approved access with the newly requested access before you approve.Optional trusted-CIDR node auto-approve
Device pairing remains manual by default. For tightly controlled node networks, you can opt in to first-time node auto-approval with explicit CIDRs or exact IPs:role: node pairing requests with no requested
scopes. Operator, browser, Control UI, and WebChat clients still require manual
approval. Role, scope, metadata, and public-key changes still require manual
approval.
Node pairing state storage
Stored in the shared SQLite state database at~/.openclaw/state/openclaw.sqlite:
- pending device pairing requests (short-lived; they expire after 5 minutes)
- paired devices + tokens
~/.openclaw/devices/*.json; those files are
imported into SQLite at gateway startup and archived with a .migrated suffix.
Notes
- The
node.pair.*API (CLI:openclaw nodes pending|approve|reject|remove|rename) manages node capability approvals stored on the same paired device records. WS nodes still require device pairing; see Node pairing. - The pairing record is the durable source of truth for approved roles. Active device tokens stay bounded to that approved role set; a stray token entry outside the approved roles does not create new access.