Access Groups: Reusable Sender Allowlists for Channels
Learn how to define named sender groups with accessGroups and reference them in channel allowlists using accessGroup:<name>. Ideal for managing consistent sender permissions across multiple messaging channels.
Read this when
- Configuring the same allowlist across multiple message channels
- Sharing DM and group sender access rules
- Reviewing message-channel access control
Access groups are named collections of senders that you set up once using accessGroups, then pull into channel allowlists through accessGroup:<name>.
They come in handy when the same individuals need access to multiple messaging channels, or when a single trusted set should govern both DM and group sender authorization.
Defining a group by itself grants nothing. It only takes effect when an allowlist field points to it.
Static message sender groups
Static sender groups rely on type: "message.senders". The members structure is organized by message-channel id, with "*" covering entries that apply across all channels:
{
accessGroups: {
operators: {
type: "message.senders",
members: {
"*": ["global-owner-id"],
discord: ["discord:123456789012345678"],
telegram: ["987654321"],
whatsapp: ["+15551234567"],
},
},
},
}
| Key | Meaning |
|---|---|
"*" | Entries that apply to every message channel referencing the group. |
discord, telegram, ... | Entries that apply only to that channel's allowlist matching. |
Matching follows the destination channel's standard allowFrom rules. OpenClaw does not map sender ids between channels: if Alice has separate Telegram and Discord ids, both need to appear under the appropriate channel keys.
Reference groups from allowlists
You can reference a group with accessGroup:<name> at any point where the message channel path supports sender allowlists.
DM allowlist example:
{
accessGroups: {
operators: {
type: "message.senders",
members: {
discord: ["discord:123456789012345678"],
telegram: ["987654321"],
},
},
},
channels: {
discord: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:operators"],
},
telegram: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:operators"],
},
},
}
Group sender allowlist example:
{
accessGroups: {
oncall: {
type: "message.senders",
members: {
whatsapp: ["+15551234567"],
googlechat: ["users/1234567890"],
},
},
},
channels: {
whatsapp: {
groupPolicy: "allowlist",
groupAllowFrom: ["accessGroup:oncall"],
},
googlechat: {
groups: {
"spaces/AAA": {
users: ["accessGroup:oncall"],
},
},
},
},
}
Groups and direct entries can be combined:
{
channels: {
discord: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:operators", "discord:123456789012345678"],
},
},
}
Supported message-channel paths
Access groups function within the shared message-channel authorization paths:
- DM sender allowlists like
channels.<channel>.allowFrom - group sender allowlists like
channels.<channel>.groupAllowFrom - channel-specific per-room sender allowlists that follow the same sender matching rules (for instance Google Chat
groups.<space>.users) - command authorization paths that reuse message-channel sender allowlists
Whether a channel supports this depends on its wiring through the shared OpenClaw sender-authorization helpers. The currently supported channel integrations are ClickClack, Discord, Feishu, Google Chat, iMessage, IRC, LINE, Mattermost, Microsoft Teams, Nextcloud Talk, Nostr, QQ Bot, Signal, Slack, SMS, Telegram, WhatsApp, Zalo, and Zalo Personal. Static message.senders groups are channel-agnostic, so new message channels pick them up automatically by relying on the shared plugin SDK ingress helpers rather than custom allowlist expansion.
Discord channel audiences
Discord offers an additional dynamic access group type:
{
accessGroups: {
maintainers: {
type: "discord.channelAudience",
guildId: "1456350064065904867",
channelId: "1456744319972282449",
membership: "canViewChannel",
},
},
channels: {
discord: {
dmPolicy: "allowlist",
allowFrom: ["accessGroup:maintainers"],
},
},
}
discord.channelAudience translates to "allow Discord DM senders who can currently view this guild channel." At authorization time, OpenClaw resolves the sender through Discord and applies Discord ViewChannel permission rules. membership is optional, defaulting to canViewChannel.
This fits when a Discord channel already serves as the source of truth for a team, such as #maintainers or #on-call.
Requirements and failure behavior:
- The bot must have access to the guild and channel.
- The Discord Developer Portal Server Members Intent must be enabled for the bot.
- The access group fails closed when Discord returns
Missing Access, the sender cannot be resolved as a guild member, or the channel belongs to another guild.
Additional Discord-specific examples: Discord access control
Plugin diagnostics
Plugin authors can read structured access-group state without flattening it back into an allowlist:
import { resolveAccessGroupAllowFromState } from "openclaw/plugin-sdk/access-groups";
const state = await resolveAccessGroupAllowFromState({
accessGroups: cfg.accessGroups,
allowFrom: channelConfig.allowFrom,
channel: "my-channel",
accountId: "default",
senderId,
isSenderAllowed,
});
The result reports which groups are referenced, matched, missing, unsupported, and failed. This is useful for diagnostics or conformance tests. Use expandAllowFromWithAccessGroups(...) only for compatibility paths that still expect a flat allowFrom array.
Security notes
- Access groups act as allowlist aliases, not roles. On their own, they do not create owners, approve pairing requests, or grant tool permissions.
dmPolicy: "open"still requires"*"in the effective DM allowlist. Referencing an access group does not equal public access.- Missing group names fail closed. If
allowFromcontainsaccessGroup:operatorsandaccessGroups.operatorsis absent, that entry authorizes no one. - Keep channel ids stable. When a channel supports both, prefer numeric/user ids over display names.
Troubleshooting
If a sender should match but is blocked:
- Verify the allowlist field holds the exact
accessGroup:<name>reference. - Verify
accessGroups.<name>.typeis correct. - Verify the sender id appears under the matching channel key, or under
"*". - Verify the entry uses that channel's normal allowlist syntax.
- For Discord channel audiences, verify the bot can see the guild channel and has Server Members Intent enabled.
Run openclaw doctor after editing access-control config. It catches many invalid allowlist and policy combinations before runtime.