You don’t need to understand the technical details to use this feature. The configuration examples below are copy-paste ready.
The one rule that matters
Comis isolates by agent, not by person. Each agent has its own memory, its own secrets, its own budget, and its own tool policy. So the question “how do I keep my users separate?” comes down to one decision:- People who should share knowledge (one team, one family) → point them at one shared agent.
- People who must stay private from each other (different clients, departments) → give each their own agent, and route to it.
Do users see each other’s messages?
Short answer: no - not their messages. The only thing a shared agent pools is what it has learned over time. Here is each layer:| Layer | Are two users isolated? | Why |
|---|---|---|
| Telegram transport (DMs) | ✅ Yes | A private 1:1 chat with the bot is invisible to everyone else - Telegram enforces this. One bot serves unlimited private DMs. |
| Telegram transport (groups) | ❌ No (by design) | Everyone in a group sees the group’s messages. That is what a group is - use DMs for privacy. |
| Comis conversation/session | ✅ Yes (default) | The default per-channel-peer session gives each person their own thread. User A’s transcript never enters User B’s session. |
| Agent long-term memory | ⚠️ Only if they use different agents | An agent’s learned facts are scoped to the agent. Two people on the same agent draw on the same memory; give them separate agents for full separation. |
Setup A - one shared agent (a team that shares knowledge)
The simplest case. Everyone DMs the same bot and talks to the same agent. Their conversations are already private (Telegram DMs + per-peer sessions); they share the agent’s learned memory, which is usually what a single team wants.routing.defaultAgentId is default, and the default
session scope already keeps each person’s chat separate.
Setup B - one agent per person or team (full isolation)
When people must stay private from each other, give each their own agent and use top-level routing to send each person (or group) to their agent. Because each agent is its own isolation boundary, this separates memory, secrets, and budget - not just the conversation.channelId for a specific
chat/group, or guildId for a Discord server).
Routing bindings are ranked by specificity:
peerId (8) > channelId (4) >
guildId (2) > channelType (1), and the first match wins for equal weight.
Full details and cross-channel examples in Multi-agent routing.The building blocks
Four independent levers cover every multi-user setup. Mix them as needed.1. Access control - who can use the bot at all
channels.<type>.allowFrom is an allowlist of sender IDs. Empty (the
default) means anyone can talk to the bot; list IDs to lock it down.
2. Conversation isolation - how sessions are split
Each agent’ssession.dmScope.mode controls how DM conversations are keyed.
The default already isolates per person; change it only if you want a single
shared thread.
mode | Effect |
|---|---|
per-channel-peer (default) | One session per channel + person. Each user’s DM is its own thread. |
per-peer | One session per person, shared across channels (their Telegram and Discord DMs merge). |
main | All DMs share one session - everyone talks into the same thread. Avoid for multi-user. |
per-account-channel-peer | Adds the bot-account identifier to the key (for multi-bot session isolation). |
3. Agent routing - who talks to which agent
Top-levelrouting maps people, chats, groups, or whole channels to a specific
agent (Setup B above). This is the lever that gives memory/secret/budget
isolation, because each agent is its own tenant. See
Multi-agent routing.
4. Trust-based replies - different treatment per person (advanced)
Give known operators a different model or system prompt than strangers, within a single agent, viaagents.<id>.elevatedReply. You assign each sender a trust
label (a name you choose), then map labels to model routes and prompt
overrides.
Trust labels are free-form strings you define - there is no fixed
admin/member/guest list.
elevatedReply changes the model and system prompt
per trust level; it does not replace allowFrom (access) or routing (agent
isolation). Use it on top of them when different people need different
capabilities from the same agent.Telegram specifics
- For privacy between users, use DMs. Each person starts a private chat with the bot; Telegram keeps those chats mutually invisible. No setup required.
- Groups are shared by design. Everyone in a Telegram group sees the group’s messages. Use a group when you want shared context, not for per-user privacy.
- Finding IDs for
allowFrom/ routing: a user’s numeric Telegram ID and a group’s chat ID both appear in the logs on every inbound message (senderId,chatId). See Finding a group’s chat ID and theallowFromsteps on the Telegram page.
Other channels
The same four levers work on every channel. Only two things change per platform: the routing-key field you bind on, and the sender-ID format you put inallowFrom. A private 1:1 (DM / direct chat) is transport-isolated on every
platform; shared spaces (groups, servers, channels) are shared by design.
| Channel | Private 1:1 | Shared space | Route a shared space with | allowFrom sender ID |
|---|---|---|---|---|
| Telegram | DM | group / supergroup | channelId (chat ID, negative) | numeric user ID |
| Discord | DM | server → channel | guildId (server) and/or channelId | numeric user ID |
| Slack | DM | workspace → channel | channelId (C…) | user ID (U…) |
| 1:1 chat | group | channelId (group JID …@g.us) | E.164 phone (+1…) | |
| Signal | 1:1 chat | group | channelId (group:<id>) | phone or UUID |
| iMessage | 1:1 chat | group | channelId (chat GUID) | phone or email |
| LINE | 1:1 | group / room | channelId (group/room ID) | LINE user ID (U…) |
| IRC | private message | channel (#name) | channelId (#channel) | nick ⚠️ |
| thread | - (1:many by recipients) | route by channelType: email | email address |
peerId (the sender) works on every platform. guildId is Discord-only -
it’s the server ID; every other platform routes a shared space with channelId.
Platform caveats for multi-user
A few platforms need extra care when several people share one install:- IRC - nicks are spoofable. IRC nicknames aren’t authenticated by default,
so
allowFromon IRC is not a security boundary unless your network enforces registration (NickServ) and you trust it. Don’t gate a sensitive agent on an IRC nick alone. - Email - the From address isn’t verified.
channels.email.allowModeisallowlistby default (only listed addresses reach the agent; setopento accept all). But sender addresses can be spoofed and Comis does not check SPF/DKIM/DMARC, so treat the email allowlist as convenience, not strong authentication, for high-stakes agents. - WhatsApp, Signal, iMessage, Email are personal accounts, not bots. The
adapter is bound to one phone number (WhatsApp/Signal), one Apple ID on macOS
(iMessage), or one mailbox (Email) - so “one bot per channel” is really “one
account per channel.” Everyone talks to that single number/address; you still
isolate people with per-person agents via
routing, they just all see the same identity. - Slack & Discord are team-native. A Slack workspace or Discord server is
already a multi-user space;
allowFromgates at the bot/workspace level (a user can or cannot reach the bot at all), and you split people across agents withroutingas usual.
One identity per channel
Each Comis daemon runs one identity per channel type - one Telegram/Discord/ Slack/LINE bot, one WhatsApp or Signal phone number, one iMessage Apple ID, one mailbox. That is not a limit on users (one identity serves unlimited private DMs and shared spaces); it only means you can’t run two different identities of the same type (two Telegram@usernames, two phone numbers) in a single daemon. If
you genuinely need a second identity, run one daemon per identity - see
Routing to a separate bot identity on
the Telegram page.
Multi-agent routing
The full routing schema, specificity rules, and cross-channel examples.
Sessions
How conversations are keyed and isolated per person, channel, and topic.
Memory
What an agent learns and stores - and why memory is scoped per agent.
Telegram setup
Step-by-step bot creation, groups, channels, and troubleshooting.
