Chapter 13: Security, Pairing & Allowlists
OpenClaw is designed to be exposed to the internet โ your bot listens on Telegram, WhatsApp, Slack, and other channels where anyone can try to send it a message. This chapter explains every layer of protection that keeps unauthorized users out and your AI costs under control.
The Security Model
OpenClaw uses a layered security approach:
- Channel authentication โ the messaging platform verifies the sender's identity
- Allowlist filtering โ OpenClaw checks whether that identity is permitted
- Workspace matching โ the matched workspace limits what the user can do
- Rate limiting โ prevents abuse even from authorized users
- Skill sandboxing โ tools the AI can use are scoped and restricted
Allowlists
Every workspace has an allowlist field that controls who can use it. When a message arrives, OpenClaw resolves the sender's channel-native ID and checks it against the allowlist of each workspace in order.
{
"workspaces": [
{
"id": "admins",
"agent": "claude-opus",
"allowlist": ["U01ADMIN", "U02ADMIN"]
},
{
"id": "team",
"agent": "claude-sonnet",
"allowlist": ["U03DEV", "U04DEV", "U05DEV"]
},
{
"id": "public",
"agent": "claude-haiku",
"allowlist": ["*"]
}
]
}
The wildcard "*" matches any user not matched by a previous workspace. Order matters โ put restrictive workspaces first.
Finding Channel User IDs
| Channel | How to Find the User ID |
|---|---|
| Telegram | Send /id to @userinfobot, or check gateway logs |
Phone number in E.164 format: +12125550100 | |
| Slack | Right-click username โ Copy member ID |
| Discord | Enable Developer Mode โ right-click user โ Copy ID |
| Teams | Check Azure AD or gateway logs |
| Signal | Phone number in E.164 format |
Logging Unknown Senders
Turn on debug logging to see who is trying to reach your bot:
openclaw --log-level debug
Any message from an unknown sender will log:
[gateway] Unauthorized sender: telegram:123456789 โ no workspace matched
Pairing Mode
Rather than looking up IDs manually, OpenClaw supports a pairing flow where users identify themselves to the gateway interactively.
Enable Pairing
{
"security": {
"pairing": {
"enabled": true,
"pairingCommand": "/pair",
"pairingSecret": "${PAIRING_SECRET}",
"autoApprove": false,
"adminNotifyWorkspace": "admins"
}
}
}
The Pairing Flow
- A new user sends
/pairto the bot - OpenClaw responds with a pairing request message and their channel user ID
- If
autoApprove: false, the gateway notifies the admin workspace - An admin runs
/approve <user-id> <workspace-id>to grant access - OpenClaw adds the user to the allowlist and reloads config
- The user is notified and can start chatting
Manual Approval Command
/approve telegram:987654321 team
This adds 987654321 to the team workspace allowlist and saves the config.
Unauthorized Responses
Control what happens when an unauthorized user messages the bot:
{
"security": {
"unauthorizedResponse": "This bot is private. Contact admin@example.com to request access.",
"silenceUnauthorized": false
}
}
Set silenceUnauthorized: true to ignore unauthorized messages completely โ the bot will not reply at all. Useful for bots you want to appear offline to non-members.
Rate Limiting
Rate limiting prevents any single user from consuming excessive API tokens:
{
"security": {
"rateLimiting": {
"enabled": true,
"maxRequestsPerMinute": 10,
"maxRequestsPerHour": 100,
"maxTokensPerDay": 100000,
"rateLimitResponse": "Slow down! You've hit the rate limit. Try again in a minute."
}
}
}
Rate limits apply per user per workspace. An admin workspace can have higher limits than a public workspace.
Per-Workspace Rate Limits
Override the global rate limit for a specific workspace:
{
"workspaces": [
{
"id": "public",
"agent": "claude-haiku",
"allowlist": ["*"],
"rateLimiting": {
"maxRequestsPerMinute": 3,
"maxRequestsPerHour": 20
}
}
]
}
Webhook Signature Verification
For channels that use webhooks (WhatsApp, Teams, Slack), OpenClaw verifies the request signature to ensure messages actually come from the platform and not a spoofed request.
This is automatic for all supported channels โ the signing secret you configure is used to validate each incoming webhook payload. Never expose your signing secrets in logs or public repositories.
Secure Secrets Management
Always use environment variable references in your config:
{
"agents": {
"claude": {
"apiKey": "${ANTHROPIC_API_KEY}"
}
}
}
Recommended ways to set environment variables securely:
# .env file (never commit this)
ANTHROPIC_API_KEY=sk-ant-...
TELEGRAM_BOT_TOKEN=1234567890:ABC...
PAIRING_SECRET=my-secret-string
# Load with dotenv
openclaw --env-file .env
Or use a secrets manager like AWS Secrets Manager, HashiCorp Vault, or Docker secrets.
Session Security
Sessions link a channel user to a conversation history. Control session expiry to limit how long a compromised session could be reused:
{
"workspaces": [
{
"id": "team",
"sessionTimeout": 3600
}
]
}
Sessions expire after sessionTimeout seconds of inactivity. Expired sessions are cleared from memory automatically.
Force-expire all sessions:
openclaw sessions clear
Audit Logging
Enable audit logging to record every message, who sent it, which workspace handled it, and what the AI responded:
{
"logging": {
"auditLog": true,
"auditLogPath": "~/.openclaw/audit.log",
"auditLogFormat": "json"
}
}
Each audit log entry includes:
{
"timestamp": "2026-04-30T12:34:56Z",
"channel": "telegram",
"userId": "123456789",
"workspaceId": "team",
"messageLength": 142,
"responseLength": 891,
"tokensUsed": 1024,
"latencyMs": 2340
}
Next: Chapter 14 โ Agents & Model Routing โ How to define multiple AI agents and route different users or tasks to different models.