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.

Diagram

Access Groups

📇 access_groups:
admins, team

✈️ Telegram
allowed_users: group:team

💬 Discord
allowed_users: group:admins

💼 Slack
allowlist: group:team

Quick Start

  1. 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
  2. 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.

Diagram
ChannelsGatewayOperatorChannelsGatewayOperatorEdit access_groupsReload and expand group:nameConcrete ids for allowed_users / allowlist / blocklistEvery channel sees the new membership
RuleBehaviour
Referencegroup:<name> inside allowed_users, allowlist or blocklist
NestingA group can contain group:<other>
OrderFirst-seen order kept, duplicates removed
StringsComma-separated values are split into ids

Configuration

Each group value can take three shapes.

List

yaml
access_groups:
  admins: ["111", "222"]

Comma string

yaml
access_groups:
  admins: "111, 222"

Env-backed

yaml
# 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.

ProblemError
Unknown groupUnknown access group: 'nope'
Cycle (a → b → a)Access group cycle: a -> b -> a
text
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

SupportedNot available yet
Gateway channels (gateway.yaml → access_groups:)Route-level references on RouteBinding
allowed_users, allowlist, blocklistStandalone bot.yaml
An access-group CLI
expand_access_groups (Python)

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.


Related