๐Ÿ”
AdvancedChapter 28 of 33ยท 4 min read

Chapter 28: Multi-Workspace Deployments

As your OpenClaw deployment grows, you'll serve more teams, more use cases, and more channels from the same gateway. This chapter covers advanced patterns for managing complex multi-workspace deployments: workspace inheritance, dynamic provisioning, workspace groups, and cross-workspace communication.


Workspace Hierarchy

For large deployments, workspaces can inherit from a base template:

{
  "workspaceDefaults": {
    "agent": "balanced",
    "sessionTimeout": 1800,
    "skills": ["web-search", "memory"],
    "rateLimiting": {
      "maxRequestsPerMinute": 10,
      "maxRequestsPerHour": 100
    }
  },
  "workspaces": [
    {
      "id": "frontend-team",
      "label": "Frontend Engineers",
      "allowlist": ["U01FE1", "U01FE2"],
      "skills": ["web-search", "memory", "github", "bash"]
    },
    {
      "id": "design-team",
      "label": "Design Team",
      "allowlist": ["U01DS1", "U01DS2"],
      "agent": "fast",
      "skills": ["web-search", "memory", "image-generation"]
    }
  ]
}

Both workspaces inherit sessionTimeout, rateLimiting, and base skills from workspaceDefaults, then override what they need.


Workspace Groups

Group workspaces together for shared policies:

{
  "workspaceGroups": [
    {
      "id": "engineering",
      "label": "Engineering Division",
      "workspaces": ["frontend-team", "backend-team", "devops-team"],
      "sharedSkills": ["github", "bash"],
      "rateLimiting": {
        "groupLimit": 1000
      }
    },
    {
      "id": "leadership",
      "label": "Leadership",
      "workspaces": ["executives", "managers"],
      "sharedSkills": ["web-search"],
      "agent": "expert"
    }
  ]
}

The group-level rateLimiting.groupLimit caps the total requests across all workspaces in the group โ€” preventing one team from consuming resources that block others.


Dynamic Workspace Provisioning

For SaaS-style deployments where each customer or team gets their own workspace, manage workspaces through the API instead of static config:

POST /api/v1/workspaces
Authorization: Bearer your-api-key

{
  "id": "customer-12345",
  "label": "Acme Corp",
  "agent": "balanced",
  "systemPrompt": "You are an assistant for Acme Corp. Always be professional.",
  "allowlist": ["whatsapp:+12125550100"],
  "skills": ["web-search"],
  "sessionTimeout": 1800,
  "metadata": {
    "customerId": "12345",
    "plan": "pro"
  }
}

Workspaces created via API are stored in the database and persist across restarts (requires sessionStore: "redis" or "postgres").

# Required for dynamic workspaces
openclaw config set sessionStore redis
openclaw config set workspaceStore redis

Workspace-Aware System Prompts

Inject workspace-specific context into the system prompt using template variables:

{
  "workspaces": [
    {
      "id": "customer-12345",
      "label": "Acme Corp",
      "systemPrompt": "You are an AI assistant for {{workspace.label}}. The current date is {{date}}. Customer ID: {{workspace.metadata.customerId}}. Always be professional and concise."
    }
  ]
}

Available variables in system prompts:

VariableValue
{{workspace.id}}Workspace ID
{{workspace.label}}Workspace label
{{workspace.metadata.*}}Custom metadata fields
{{date}}Current date
{{datetime}}Current datetime
{{user.id}}Channel user ID

Cross-Workspace Routing

Route a user to a different workspace based on context:

{
  "workspaces": [
    {
      "id": "triage",
      "agent": "fast",
      "allowlist": ["*"],
      "routing": {
        "rules": [
          {
            "if": "message contains 'urgent' or 'critical' or 'down'",
            "routeTo": "oncall"
          },
          {
            "if": "message starts with '/code'",
            "routeTo": "dev-team"
          }
        ]
      }
    },
    { "id": "oncall", "agent": "expert", "allowlist": ["*"] },
    { "id": "dev-team", "agent": "balanced", "allowlist": ["*"] }
  ]
}

The triage workspace handles all initial messages. If a routing rule matches, the message is re-dispatched to the target workspace transparently.


Workspace Namespacing by Channel

Different channels can default to different workspaces:

{
  "channels": {
    "telegram": {
      "enabled": true,
      "token": "${TELEGRAM_BOT_TOKEN}",
      "defaultWorkspace": "public"
    },
    "slack": {
      "enabled": true,
      "botToken": "${SLACK_BOT_TOKEN}",
      "defaultWorkspace": "dev-team"
    }
  }
}

Telegram users land in public by default; Slack users land in dev-team. The allowlist in each workspace further refines who can access it.


Workspace-Scoped Monitoring

Monitor each workspace independently:

# Stats for a specific workspace
openclaw stats workspace frontend-team

# Compare workspaces
openclaw stats workspaces --compare

# Usage breakdown by workspace
openclaw stats workspaces --period 7d
Workspace        Messages   Tokens     Sessions   Avg Response
---------------- ---------- ---------- ---------- ------------
frontend-team    1,240      1.8M       89         1,840ms
backend-team     980        2.1M       71         2,100ms
design-team      340        420K       28         1,200ms
executives       82         310K       14         4,200ms

Workspace Migration

Move a user from one workspace to another without losing their session history:

openclaw workspace migrate-user U01DEV1 from:frontend-team to:backend-team

Or via API:

POST /api/v1/workspaces/migrate-user
{
  "userId": "slack:U01DEV1",
  "fromWorkspace": "frontend-team",
  "toWorkspace": "backend-team",
  "preserveSession": true
}

Archiving and Suspending Workspaces

# Suspend (stop accepting new messages, preserve data)
openclaw workspace suspend customer-12345

# Archive (mark as read-only, accessible for export)
openclaw workspace archive customer-12345

# Delete (permanent)
openclaw workspace delete customer-12345 --confirm

Next: Chapter 29 โ€” CI/CD Integration โ€” How to test and deploy OpenClaw config changes through automated pipelines.