OpenClaw Session Keys Explained: How One Gateway Keeps 24 Channels Separate in 2026
An OpenClaw session key is the unique string that tells the gateway which conversation a message belongs to. Here is how session keys work, how dmScope isolates DMs across WhatsApp, Slack, Discord, and 20+ other channels, and how to configure them for a multi-client agency without leaking context between users.
Last updated: April 20, 2026
An OpenClaw session key is the unique identifier the gateway attaches to every incoming message so the AI agent knows which conversation it belongs to and which context to load. Each channel, each user, and each thread produces a different key. That one string is what lets a single OpenClaw gateway run a WhatsApp DM, a Slack thread, a Discord guild channel, and the browser WebChat widget side by side without any of them reading the others' memory. OpenClaw 2026.4.15 ships 24 supported channel integrations out of the box, and the session key is the quiet machinery that keeps every one of those conversations isolated from every other one.
Key takeaways
- Session keys are generated automatically from channel, user, and thread metadata. You normally never type one by hand, but you can override the format for multi-tenant apps.
- The
session.dmScopesetting has three modes (main,per-channel-peer,per-peer) and each one trades continuity for isolation differently. - Groups and threads always get their own session. That part is not configurable and it is the right default for group privacy.
- The OpenClaw gateway listens on port 18789 by default and resolves the session key before it ever dispatches a message to the agent runtime.
- A prefixed session key like
kyra-user-42is how multi-tenant platforms separate thousands of clients without spinning up a container per user. - Session keys solve the isolation problem at the context layer, not the infrastructure layer. One daemon, one agent pool, N clean conversations.
What an OpenClaw session key actually is
Every message that arrives at an OpenClaw gateway carries a small bundle of metadata: which channel adapter it came from (Slack, WhatsApp, Discord, Matrix, and so on), which account sent it, and whether it landed in a DM, a group, or a thread. The gateway runs that bundle through its session manager, which deterministically produces a string. That string is the session key.
The key does two jobs at once. First, it tells the agent runtime which conversation's memory, history, and working files to load before replying. Second, it tells the gateway where to route the reply once the agent is done thinking. A message with key slack:T12345:C98765:U00001 loads and writes to a different context than a message with key wa:+15551234567, even if both messages come from the same human being on the same day.
This is the core primitive behind OpenClaw's "one gateway, many channels" promise. Without the session key, every incoming message would either collapse into a single global chat (disastrous for privacy) or require a separate daemon per channel (disastrous for cost and ops). The key is the cheap, composable middle path.
Why one gateway needs many sessions
A realistic deployment for a small agency looks like this. One OpenClaw gateway on a VPS. One Anthropic API key. Fifteen client businesses, each with their own Slack workspace, WhatsApp number, or web widget. Hundreds of end users across those businesses. Every one of those users expects the AI to remember their last conversation and nothing else.
If you tried to do that with fifteen separate daemons, your ops surface would triple: fifteen systemd units to patch, fifteen logs to tail, fifteen sets of secrets to rotate. If you tried to do it with one daemon and one global conversation, the first time User A's medical question leaked into User B's session you would lose every client at once.
Session keys let you stay in the middle. One daemon still runs. One agent pool still handles the load. But every message lives in its own keyed context, and the gateway enforces the boundary before the model ever sees the prompt. This is the same pattern Cowork, Claude Code's IDE extensions, and most production OpenClaw deployments use, and it is exactly how the broader OpenClaw gateway architecture was designed to scale.
The anatomy of a session key
Session keys are plain strings, so you can look at them in a log file and read them. The default format encodes the channel, the workspace or server, the channel or room, and the user, joined with colons. Real examples from a production gateway:
slack:T09ABC123:C04XYZ789:U07DEF456โ a DM inside a specific Slack workspacediscord:guild_742:channel_9981:user_4412โ a DM-style channel in a Discord guildwa:+15551234567โ a WhatsApp DM, keyed by the peer's phone numbertelegram:chat_5839201โ a Telegram chatwebchat:anon_9d2f1cโ an anonymous browser visitor on the WebChat widgetmatrix:!room_abc:server:@user:serverโ a Matrix room with full federated identity
You can also prefix your own namespace. This is how multi-tenant hosts structure keys. A self-serve platform might force every agent's session keys to begin with tenant-42-, giving you strings like tenant-42-slack:T09ABC:C04XYZ:U07DEF. The gateway treats the prefix as opaque, but it means one tenant's Slack DM and a different tenant's identical Slack DM never collide in the session store.
The specific format is documented in the OpenClaw gateway security reference. You can override it in config.yml under session.keyFormat, but the default is good enough for 95% of deployments and you should only change it if you know exactly why.
dmScope: three ways to isolate direct messages
Groups and threads are easy. Every group gets its own session key, every thread gets its own key, and nobody disagrees about whether that is correct. DMs are the interesting case. A user who chats with the same AI persona across Slack, WhatsApp, and WebChat might want those three surfaces to feel like one continuous conversation, or they might want them to feel like three airtight rooms. OpenClaw exposes this choice through the session.dmScope setting, which has exactly three valid values.
dmScope: main (the default)
In main mode every direct message the user sends, from any channel, resolves to the same shared session. The agent remembers everything they ever said in a DM regardless of which app delivered it. This is the warmest setting and the right one for a single-user personal assistant: the OpenClaw founder chatting with their own agent from Slack in the morning and WhatsApp in the evening does not want two separate memories.
dmScope: per-channel-peer (the secure default)
In per-channel-peer mode every unique combination of channel plus sender produces its own session. Slack DMs from user Alice get one session. WhatsApp DMs from the same Alice get a different one. Discord DMs get a third. This is the right default when you deploy for other people rather than yourself. An employee who messages the AI from work Slack and personal WhatsApp probably expects those to feel like two different contexts, and HR auditors definitely expect it.
dmScope: per-peer
In per-peer mode the channel is dropped from the key and only the peer identity matters. Alice's DMs collapse into one session across every channel of the same type, but different channel types still stay separate. This is the rarest setting and is usually only useful when the underlying identity system is strong enough to trust across surfaces, for example a Matrix-federated deployment where every user has one canonical MXID.
The practical rule: start with per-channel-peer for any multi-user deployment, switch to main for a personal bot, and only reach for per-peer when a specific compliance or UX requirement demands it.
Groups, threads, and why they always get their own session
The dmScope setting only governs direct messages. Group channels and threads are treated as first-class conversations in their own right, every time, without exception. A Slack channel #general gets one session key shared by every member. A Slack thread inside that channel gets a different session key shared by every participant in the thread. The same rule applies to Discord threads, Matrix spaces, Telegram group chats, and WhatsApp groups.
This design matters for two reasons. First, groups have social norms: a message posted to #engineering is readable by the whole team, so the agent can safely load prior #engineering context when replying. Second, threads are mini-rooms: they exist specifically because the participants want a scoped side conversation, and the agent should respect that scope. OpenClaw bakes that expectation into the session layer so the developer cannot accidentally violate it.
The upshot is that dmScope only needs to worry about direct messages because everything else already has the right behavior by default. If you need to see the full precedence order the gateway uses to derive a key, the security reference lays out the full resolution algorithm.
Step-by-step: configure session keys for a multi-client agency
Here is a minimal working setup that takes an OpenClaw gateway from vanilla install to multi-client isolation. It assumes you have already installed OpenClaw and bound it to its default port. The walkthrough targets OpenClaw 2026.4.15 or later.
1. Confirm the gateway is running.
openclaw gateway status
# expected: listening on :18789, 0 active sessions
2. Open your gateway config.
$EDITOR ~/.openclaw/config.yml
3. Set the DM scope and enable tenant prefixing. This is the single most important block for multi-client deployments. Every session key will now carry the tenant prefix, and DMs will isolate per channel plus peer.
session:
dmScope: per-channel-peer
keyFormat: "tenant-{tenant_id}-{channel}:{server_id}:{channel_id}:{user_id}"
ttlDays: 30
storage: sqlite
storagePath: ~/.openclaw/sessions.db
4. Add two channel adapters for a first smoke test. Slack and WebChat are the fastest to wire up because neither requires a verified phone number.
channels:
- type: slack
botToken: ${SLACK_BOT_TOKEN}
signingSecret: ${SLACK_SIGNING_SECRET}
tenant_id: "42"
- type: webchat
publicUrl: https://chat.example.com
tenant_id: "42"
5. Reload the gateway without dropping active sessions.
openclaw gateway reload
6. Send one test message from each surface. Slack DM first, then a WebChat visit from an incognito browser. Then run the session listing command.
openclaw sessions list --tenant 42
# expected: two rows, one slack session, one webchat session,
# both prefixed with tenant-42-
7. Verify isolation with a one-line check. Ask the agent in Slack what it remembers. Ask the same question in WebChat. The answers must differ. If they don't, your dmScope is wrong or your keyFormat is collapsing the two keys into one.
That is it. The config file and the seven commands above are a complete per-tenant session isolation setup. Every client you add later is one more entry in the channels: array with a different tenant_id, plus whatever per-client skills or memory you want to layer on top. For the broader walkthrough that includes MCP connectors and Claude Skills, those two companion guides pick up where this one stops.
Comparison: session isolation strategies across AI gateways
Session isolation is not an OpenClaw-specific idea, but the shape of the implementation varies widely across the ecosystem. Here is how the four patterns most teams will encounter in 2026 actually differ.
| Strategy | What gets isolated | Typical implementation | Cost per extra user |
|---|---|---|---|
| Session key (OpenClaw) | Conversation context, memory, working files | One daemon, keyed context store | A few KB of session state |
| Container per tenant | Everything, including CPU and filesystem | One container per client, orchestrator on top | 50โ200 MB RAM minimum per user |
| Thread per request (classic chatbot) | Nothing beyond one turn | Stateless API call, memory pushed to a DB | Round-trips to external memory on every turn |
| Claude Managed Agents | Sandboxed execution, long-running sessions | Anthropic-hosted infrastructure (public beta, April 2026) | Per-session metered pricing |
Session keys give you conversation-level isolation at near-zero marginal cost, which is why they dominate multi-tenant self-hosted deployments. Containers give you infrastructure-level isolation, which matters when you run untrusted code and you are willing to pay the RAM bill. Anthropic's Claude Managed Agents, launched in public beta on April 8, 2026, sit at the other end of the spectrum: you pay Anthropic to host the isolation boundary and stop worrying about it yourself. Most Kyra-style deployments pick the session key path because it keeps the stack thin.
When session keys aren't the right answer for you
Session keys solve context isolation. They do not solve everything, and there are three situations where reaching for a different primitive is the correct move.
You run untrusted code on behalf of users. If your agent executes arbitrary Python or shell that a user can control, context isolation is necessary but not sufficient. You want a real sandbox boundary: a container, a firecracker VM, or Claude Managed Agents. Session keys stop a user from reading another user's conversation, but they do not stop one user's shell command from reading the daemon's filesystem.
You have strict regulatory isolation requirements. Some HIPAA, GDPR, or FedRAMP deployments contractually require that two tenants' data never share a process, period. Session keys share a process by design. If your compliance officer is in the conversation, plan for a container-per-tenant or a dedicated gateway-per-tenant architecture from day one.
You want a stateless protocol. The MCP working group is actively evolving the protocol toward stateless requests in 2026 for the same load-balancer and horizontal-scaling reasons that session state creates. If your deployment is behind a round-robin load balancer across many stateless server instances, OpenClaw's keyed session store assumes the load balancer is sticky (or assumes a shared session DB). Pick accordingly, and check the MCP 2026 roadmap if you are making long-range architecture bets.
For the other 80% of deployments (agencies with tens to low hundreds of clients, founders running a personal assistant across every app they use, GHL resellers adding an AI worker per client), session keys are boringly correct.
Frequently asked questions
How does OpenClaw decide which agent handles a given session key?
The gateway reads a routing: block in the config that maps channel patterns to agent names. A route like slack:T09ABC*:* -> agent-acme sends every Slack message from workspace T09ABC to the Acme agent, regardless of which user or channel triggered it. Session keys are derived first, then routing picks the agent, then the agent loads the session's context. All three steps happen before the model sees a single token.
Can I share a session key across two users intentionally?
Yes. Set session.keyFormat to a value that ignores the user portion, for example "{channel}:{server_id}:{channel_id}". Every user in that channel will then write to the same context. This is useful for a shared workspace assistant where the team expects a continuous thread of memory. Use it on purpose, not by accident.
What happens when a session key is rotated or expired?
Sessions have a TTL (default 30 days). When the TTL lapses, the gateway archives the conversation and returns a cold context for the next message with that key. The user sees the AI "forget" the old conversation. To keep the memory forever, set session.ttlDays to 0 and budget for your session store to grow over time.
Can I look up a session key from a user's name?
Yes, through the admin API. openclaw sessions find --channel slack --user U07DEF456 returns the full session key and metadata. This is how support teams pull up a user's conversation history when they file a ticket. Access is gated by the gateway's admin token, not by the agent, so users cannot read each other's sessions even if they have agent-level tool access.
Does this work the same way in a Cowork deployment?
Yes. Cowork adds a workspace layer on top of the gateway, but the session key primitive is the same. A Cowork workspace contributes one more segment to the key (the workspace ID), which is how a single physical gateway can host many Cowork tenants without any of them seeing each other's sessions.
How do I debug a session that is routing to the wrong agent?
Run the gateway with OPENCLAW_LOG=debug and watch the "session resolved" and "routing matched" log lines for the incoming message. Nine times out of ten the issue is a missing or wrong tenant_id on the channel, or a routing pattern that matches more aggressively than you expected. The third time it is an outdated cache, which openclaw gateway reload fixes.
The small idea that makes multi-channel AI practical
Session keys are a small idea and they do a surprising amount of work. They are why one OpenClaw daemon can run 15 clients without cross-talk. They are why a personal assistant can feel continuous across Slack and WhatsApp or crisply separated, depending on a single config line. They are why agencies can charge recurring fees for AI workers without standing up a container farm to host them. The format is five minutes of reading in the docs, and the implications show up in every architectural decision downstream.
If you want the OpenClaw gateway, the session key defaults, and the per-client isolation wired up for you rather than configured by hand, Kyra runs the whole stack on your own domain with tenant prefixes and per-channel-peer isolation turned on from the first install. For industry-specific starting points there are ready-made worker templates for dental practices and real estate agencies, and for the architectural picture behind all of this, the OpenClaw repository on GitHub and the gateway security reference are the two most useful places to keep bookmarked. Session keys are the kind of primitive you only notice when they fail, and when they are set up right you should never have to think about them again.
The Kyra Team
Conversion System
We build white-label AI workforce infrastructure for digital agencies on top of OpenClaw. We publish practical guides on deploying AI agents, self-hosted AI, and multi-channel workforce design.
Try Kyra free
No credit card. Powered by OpenClaw. First AI worker live in under 2 minutes.
Related reading
AI Infrastructure
AI Agent Memory Systems in 2026: How OpenClaw Workspaces, SOUL.md, and Context Compaction Actually Work
13 min read
AI Infrastructure
Self-Hosted AI Cost vs Cloud LLM Bills in 2026: The Honest Math for Agencies
16 min read
AI Infrastructure
Per-Client AI Container Isolation in 2026: How Agencies Run 50+ AI Workers Without Cross-Contamination
12 min read