Access Groups
Define a set of senders once and reference it from any channel's allow/block list.
Access groups let you name a set of senders once and reference it from any channel — one definition, one revoke point.
Quick Start
- Define a group, use it in a channel
gateway.yaml agents: assistant: { instructions: "Help the user." } access_groups: admins: ["111", "222"] channels: telegram: token: ${TELEGRAM_BOT_TOKEN} allowed_users: ["group:admins"] # expands to ["111", "222"]bash praisonai gateway start --config gateway.yaml - Nest groups and share across channels
gateway.yaml agents: assistant: { instructions: "Help the user." } access_groups: admins: ["111", "222"] team: ["group:admins", "333"] # groups may nest channels: telegram: token: ${TELEGRAM_BOT_TOKEN} allowed_users: ["group:team"] # expands to ["111", "222", "333"] discord: token: ${DISCORD_BOT_TOKEN} allowed_users: ["group:admins"] # expands to ["111", "222"] blocklist: ["999"]
How It Works
Expansion happens once at config load, before validation and admission, so every channel admits from the same definition.
| Rule | Behaviour |
|---|---|
| Reference | group:<name> inside allowed_users, allowlist or blocklist |
| Nesting | A group can contain group:<other> |
| Order | First-seen order kept, duplicates removed |
| Strings | Comma-separated values are split into ids |
Configuration
Each group value can take three shapes.
List
access_groups:
admins: ["111", "222"]Comma string
access_groups:
admins: "111, 222"Env-backed
# ADMINS=111,222
access_groups:
admins: ["${ADMINS}"]
channels:
discord:
token: ${DISCORD_BOT_TOKEN}
allowed_users: ["group:admins"] # ["111", "222"]Fail-Closed Behaviour
A bad reference stops the gateway instead of silently widening or narrowing access.
| Problem | Error |
|---|---|
| Unknown group | Unknown access group: 'nope' |
Cycle (a → b → a) | Access group cycle: a -> b -> a |
Gateway config validation failed (gateway.yaml):
- channels.telegram.allowed_users: Unknown access group: 'nope'On hot-reload, a bad reference keeps the last-known-good config.
Common Patterns
One team, three channels
Reference group:team from Telegram, Discord and Slack. Remove a person from team once and they lose access everywhere.
Env-backed groups
Keep ids out of the file with admins: ["${ADMINS}"] and set ADMINS=111,222.
Nested roles
Put group:admins inside team so admins are automatically team members.
Scope
| Supported | Not available yet |
|---|---|
Gateway channels (gateway.yaml → access_groups:) | Route-level references on RouteBinding |
allowed_users, allowlist, blocklist | Standalone bot.yaml |
An access-group CLI |
Pure, zero-dependency expansion used by the gateway loader.
Best Practices
Define once, reference everywhere
Never re-paste raw ids into each channel — they drift.
Use simple group names
Lowercase names such as admins or on_call are easy to spot in reviews.
Model roles with nesting
Build hierarchies like admins ⊂ oncall ⊂ team.
Keep the strict default
Pair groups with unknown_user_policy: "deny". See Channel Security.