Introduction
Once your OpenClaw gateway is publicly accessible, anyone who knows your bot account can interact with it — which means potential API cost overruns and privacy risks. OpenClaw provides multi-layered access control mechanisms: from global allowlists to per-group and per-channel fine-grained permissions, giving you precise control over who can use the AI.
Access Control Architecture
OpenClaw evaluates permissions in the following priority order:
Global Blacklist (highest priority, immediate denial)
↓
Channel-Level Allowlist
↓
Group Allowlist
↓
User Allowlist
↓
Global Default Policy (allow or deny)
If a request is rejected at any layer, the message will not be processed. This layered design handles both simple "only allow myself" scenarios and complex multi-team permission management needs.
Global Default Policy
First, determine the global default behavior — when a message source is not in any allowlist or blacklist, should it be allowed or denied:
{
"security": {
"accessControl": {
"defaultPolicy": "deny",
"logDenied": true
}
}
}
| defaultPolicy | Behavior |
|---|---|
"allow" |
Allow everyone by default; only blacklisted users are denied |
"deny" |
Deny everyone by default; only allowlisted users are permitted |
Using "deny" is recommended — operating in allowlist mode is more secure, requiring explicit authorization before access is granted.
When logDenied is set to true, denied messages are recorded in the logs, making it easy to identify legitimate users who need to be added to the allowlist.
User Allowlist
By User ID
Each messaging platform has a unique user identifier. In openclaw.json, you can configure allowed users per channel:
{
"channels": {
"telegram": {
"enabled": true,
"token": "your-token",
"allowedUsers": [123456789, 987654321]
},
"discord": {
"enabled": true,
"token": "your-token",
"allowedUsers": ["1234567890123456", "9876543210987654"]
},
"whatsapp": {
"enabled": true,
"allowedUsers": ["+8613800138000", "+8613900139000"]
}
}
}
User ID formats vary by platform. Telegram uses numeric IDs, Discord uses snowflake IDs in string format, and WhatsApp uses phone numbers.
How to Obtain User IDs
Methods for obtaining user IDs on different platforms:
| Platform | Method |
|---|---|
| Telegram | Send a message to @userinfobot, or check the OpenClaw logs |
| Discord | Enable Developer Mode, right-click user → Copy ID |
| Use the phone number directly (including country code) | |
| Slack | Check the Member ID in the user profile |
The simplest approach is to first set defaultPolicy to "allow" so everyone can use the bot, then check the user IDs recorded in the OpenClaw logs, and finally switch to "deny" mode and add the allowlist entries.
Group Allowlist
You may want the AI to respond only in specific groups, rather than replying in any group it gets added to:
{
"channels": {
"telegram": {
"enabled": true,
"token": "your-token",
"allowedGroups": [-100123456789, -100987654321]
},
"discord": {
"enabled": true,
"token": "your-token",
"allowedChannels": ["general", "ai-chat"],
"allowedGuilds": ["1234567890"]
}
}
}
User Filtering Within Groups
Even when a group is on the allowlist, you can still restrict which users within the group can trigger the AI:
{
"channels": {
"telegram": {
"allowedGroups": [-100123456789],
"groupUserPolicy": "allowlist",
"groupAllowedUsers": {
"-100123456789": [123456789, 111222333]
}
}
}
}
This way, even in an authorized group, only specified users can trigger AI responses, while @mentions from other users will be ignored.
Global Allowlist
If you want certain users to be allowed across all channels, you can use the global allowlist to avoid repeating the configuration in each channel:
{
"security": {
"accessControl": {
"defaultPolicy": "deny",
"globalAllowlist": {
"users": ["tg:123456789", "dc:1234567890123456", "wa:+8613800138000"],
"groups": ["tg:-100123456789", "dc:1234567890"]
}
}
}
}
Identifiers in the global allowlist follow the format <channel prefix>:<ID>. Supported prefixes include:
| Prefix | Platform |
|---|---|
tg |
Telegram |
dc |
Discord |
wa |
|
sl |
Slack |
im |
iMessage |
sg |
Signal |
mx |
Matrix |
Blacklist
The blacklist takes priority over the allowlist. Even if a user is on the allowlist, they will be denied if they also appear on the blacklist:
{
"security": {
"accessControl": {
"blacklist": {
"users": ["tg:999888777"],
"groups": ["tg:-100111222333"],
"reason": {
"tg:999888777": "API abuse, banned"
}
}
}
}
}
The blacklist is suitable for handling known malicious users or abused groups.
Roles and Permissions
OpenClaw also supports a more granular role-based permission system to control what actions users can perform:
{
"security": {
"accessControl": {
"roles": {
"admin": {
"permissions": ["chat", "manage", "config", "dashboard"],
"users": ["tg:123456789"]
},
"user": {
"permissions": ["chat"],
"users": ["tg:987654321", "tg:111222333"]
},
"viewer": {
"permissions": ["chat:readonly"],
"users": ["tg:444555666"]
}
}
}
}
}
Available Permissions
| Permission | Description |
|---|---|
chat |
Chat with the AI |
chat:readonly |
View conversations only, cannot send messages |
manage |
Manage sessions (clear history, switch models, etc.) |
config |
Modify configuration (via chat commands) |
dashboard |
Access the Web Dashboard |
admin |
All permissions |
Private Message Pairing Authentication
For channels that support private message pairing (such as WhatsApp and iMessage), OpenClaw provides a pairing verification mechanism:
{
"security": {
"accessControl": {
"pairingRequired": true,
"pairingMessage": "Please send the pairing code to get started. Contact the administrator to obtain your pairing code."
}
}
}
Once enabled, new users will receive a pairing prompt when they first message the bot privately, and must enter the correct pairing code before they can start using it. Pairing codes are generated via the command line:
# Generate a one-time pairing code
openclaw access pair-code --generate
# Output: PAIR-A3F2-C1D8
# Generate a pairing code for a specific user
openclaw access pair-code --generate --user "tg:123456789"
Access Logging and Monitoring
With access logging enabled, OpenClaw records the results of all permission evaluations:
# View recent access logs
openclaw access log --tail 50
# Example output:
# 2026-03-14 14:30:22 ALLOW tg:123456789 chat "Hello"
# 2026-03-14 14:30:25 DENY tg:999888777 chat "Test" (blacklisted)
# 2026-03-14 14:31:10 DENY tg:555666777 chat "hi" (not in allowlist)
On the Dashboard's security monitoring page, you can view access statistics charts:
- Hourly/daily allow and deny counts
- Most frequently denied user IDs (which may be legitimate users who need to be added to the allowlist, or malicious probes)
- Usage distribution across channels
Practical Configuration Examples
Personal Use (allow only yourself)
{
"security": {
"accessControl": {
"defaultPolicy": "deny",
"globalAllowlist": {
"users": ["tg:123456789"]
}
}
}
}
Small Team Use
{
"security": {
"accessControl": {
"defaultPolicy": "deny",
"roles": {
"admin": {
"permissions": ["admin"],
"users": ["tg:123456789"]
},
"member": {
"permissions": ["chat", "manage"],
"users": ["tg:111111111", "tg:222222222", "tg:333333333"]
}
}
}
}
}
Public Service (abuse prevention)
{
"security": {
"accessControl": {
"defaultPolicy": "allow",
"blacklist": {
"users": ["tg:999888777"]
}
},
"rateLimit": {
"enabled": true,
"maxRequests": 10,
"windowMs": 60000
}
}
}
Summary
OpenClaw's access control system covers a wide range of scenarios from personal use to team deployment, spanning simple allowlists to role-based permissions. Key recommendations: always set defaultPolicy to "deny" in production environments, explicitly authorizing every user and group; enable logDenied to monitor denied requests; and periodically review the allowlist to remove entries that are no longer needed. Security is an ongoing process, not a one-time configuration.