OpenClaw Pairing Guide: pairing approve, dmPolicy, and What an Approval Actually Grants
The first pairing code you approve is special. Whoever sent it becomes the owner of your agent's privileged commands, and nobody you approve after them ever does.
The pages that rank for openclaw pairing do a good job on the handshake. The official pairing doc, a long troubleshooting piece with ten reasons your bot stays silent, a Telegram setup walkthrough: all three explain the code, the list and approve commands, and the dmPolicy values. None of them spends much time on the moment after you type approve. That is where the mistakes live, so this guide covers the handshake quickly and then walks through what an approval actually hands over.
How a Pairing Request Arrives
With dmPolicy: "pairing", which is the default, an unknown sender who DMs your bot gets a code back and nothing else. Their message is not processed. The code is 8 characters, uppercase, with the ambiguous ones (0, O, 1, I) left out, and it expires after one hour.
Pending requests are capped at 3 per channel account. Once three are waiting, a fourth sender gets ignored until one of them expires or you approve it. No error reaches them. If a friend swears they messaged the bot and never got a code, run pairing list before you start debugging tokens.
Listing and Approving
openclaw pairing list telegram
openclaw pairing list --channel telegram --account work --json
openclaw pairing approve telegram <CODE>
openclaw pairing approve --channel telegram --account work <CODE> --notifyRequests and approved senders are keyed by channel and account. If you run two Telegram bots, a request for the work account will not show up under the default one, so pass --account or you will stare at an empty list. --notify sends the requester a confirmation; without it they find out by trying again.
The --json output gives each request an id, the code, createdAt, lastSeenAt and optional meta. You can also approve in the Control UI under Settings → Channels → DM access requests. The CLI works with the gateway offline, which is the reason I default to it.
The Owner Bootstrap Happens Once
If commands.ownerAllowFrom is empty when you approve a code, the CLI writes the approved sender into it, as something like telegram:123456789. That entry is what makes someone the owner for privileged commands and exec approval prompts. After an owner exists, later approvals grant DM access and stop there.
Which means the order matters on a fresh install. Say you set up the bot, hand your phone to a partner to test it, and approve their code first because they happened to message first. They now hold the owner slot, and your own approval ten minutes later only lets you chat. Pair yourself first. Always. Then check:
openclaw config get commands.ownerAllowFrom --jsonIf you approved senders before version 2026.4.29, the bootstrap did not exist yet. Run openclaw doctor to set command ownership (the doctor guide covers what else it checks). And if you would rather not tie ownership to a chat handshake at all, the Control UI wizard has a "Set up my operator account" step that configures it without DM pairing.
What a Second Approval Hands Over
The CLI reference says pairing only lets a sender talk to the agent. That is true for ownership. It is looser for commands.
The access-control docs authorize commands for approved senders, and unless you set commands.allowFrom, that authorization follows the channel allowlist and pairing state. So every person you pair can use the commands your agent accepts, short of the owner-only ones. If the channel allowlist is empty or contains "*", commands are open on that channel. I set commands.allowFrom explicitly on any channel where I have paired a second human, even when I trust them, because I would rather read the list than reason about it.
The second thing that changes is context. Under the default session.dmScope of main, every DM from everyone shares one session, so your newly paired friend is effectively typing into your conversation. The session reset guide explains the scopes; the short version is to switch to per-channel-peer before you approve anyone who is not you.
Approval Is Close to Permanent
The pairing docs describe a Dismiss action for pending requests, and they are clear that it is not a block. The sender can ask again later. For senders you have already approved, neither the pairing page nor the CLI reference documents a removal command, and openclaw pairing has only list and approve. I treat every approval as permanent until that changes. If someone might need cutting off later, an explicit allowFrom list under dmPolicy: "allowlist" is easier to edit than a pairing row, and unknown senders on that policy are blocked without ever getting a code.
Where Approvals Are Stored
Current versions keep pairing state in ~/.openclaw/state/openclaw.sqlite, in the channel_pairing_requests and channel_pairing_allow_entries tables. Older pages (including an access-control section that has not caught up) still point at ~/.openclaw/credentials/<channel>-allowFrom.json. Those files are legacy. Normal startup leaves them alone and the pairing commands read only the SQLite rows, so editing the JSON does nothing. openclaw doctor --fix imports them into SQLite and deletes each file after a successful import. Back up first; the backup guide has the command.
Groups Use a Separate List
DM pairing does nothing for group chats. Group access runs through groupPolicy and groupAllowFrom, checked before mention or reply activation, and replying to one of the bot's own messages does not get a sender past groupAllowFrom. If your last security audit flagged channels.<provider>.dm.open or open groups with elevated tools, this is the section of config to fix.
Device Pairing Is a Different Command
openclaw devices list
openclaw devices approve <requestId>
openclaw devices reject <requestId>Phones and Macs connecting as nodes (role: node) go through openclaw devices, never openclaw pairing. Setup codes from the Control UI carry a bootstrap token that expires after 10 minutes. You can auto-approve from a subnet with gateway.nodes.pairing.autoApproveCidrs, but only fresh node requests with no scopes qualify. I leave it off unless I own every device on that range.
Common Failure Modes
Sender never received a code
Three requests are probably already pending on that channel account. Approve or wait out one of them (codes last an hour).
pairing list is empty but someone is waiting
The request is on another account. Add --account <id>.
Approved, but exec prompts go to someone else
The owner bootstrap already ran for an earlier approval. Check commands.ownerAllowFrom and correct it with a reviewed write, as in the config CLI guide.
Edited credentials JSON, nothing changed
Pairing reads SQLite only. Run openclaw doctor --fix to import legacy files.
Final Verdict
Keep dmPolicy on pairing, pair yourself before anyone else, and confirm the owner entry right after. Before the second human, set per-channel-peer and write commands.allowFrom by hand. Pairing is a good front door. It was never meant to be the whole permission model, and the chat integration guide is the place to start if you have not connected a channel yet.
Ready to build?
Get the OpenClaw Starter Kit — config templates, 5 production-ready skills, deployment checklist. Go from zero to running in under an hour.
$14 $6.99
Get the Starter Kit →Also in the OpenClaw store
Get the free OpenClaw quickstart guide
Step-by-step setup. Plain English. No jargon.