> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

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

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "Access Groups"
        G[📇 access_groups:<br/>admins, team] --> TG[✈️ Telegram<br/>allowed_users: group:team]
        G --> DC[💬 Discord<br/>allowed_users: group:admins]
        G --> SL[💼 Slack<br/>allowlist: group:team]
    end

    classDef groups fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef channel fill:#189AB4,stroke:#7C90A0,color:#fff

    class G groups
    class TG,DC,SL channel
```

## Quick Start

**1. Define a group, use it in a channel**

```yaml gateway.yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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 theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
praisonai gateway start --config gateway.yaml
```

**2. Nest groups and share across channels**

```yaml gateway.yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Operator
    participant Gateway
    participant Channels

    Operator->>Gateway: Edit access_groups
    Gateway->>Gateway: Reload and expand group:name
    Gateway->>Channels: Concrete ids for allowed_users / allowlist / blocklist
    Channels-->>Operator: Every channel sees the new membership
```

| 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**

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
access_groups:
  admins: ["111", "222"]
```

**Comma string**

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
access_groups:
  admins: "111, 222"
```

**Env-backed**

```yaml theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# 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` |

```text theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
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.

> [!WARNING]
>
> Access groups control who can talk to your agent. Review the full posture in [Bot Security](https://praison.ai/docs/best-practices/bot-security.md).

***

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

> **[expand\_access\_groups (Python)](https://praison.ai/docs/docs/sdk/reference/praisonaiagents/functions/expand_access_groups)**
>
> 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](https://praison.ai/docs/features/bot-gateway.md#channel-security).

***

## Related

> **[Bot Gateway](https://praison.ai/docs/features/bot-gateway.md#channel-security)**
>
> Channel Security settings

> **[Bot Security](https://praison.ai/docs/best-practices/bot-security.md)**
>
> Broader security posture

> **[Channels Gateway](https://praison.ai/docs/features/channels-gateway.md)**
>
> Shared allowlist surface

> **[Gateway Config Migration](https://praison.ai/docs/features/gateway-config-migration.md)**
>
> Gateway keys inventory


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.