* Document multi-tenant workspace architecture * Add OSS and commercial workspace boundaries * docs: redesign multi-tenant workspace architecture * feat(tenancy): implement workspace isolation * docs(tenancy): record verification evidence * docs(tenancy): revise single-instance SaaS topology * docs(tenancy): refine architecture options * docs: finalize cloud v2 multi-tenant decisions * feat(tenancy): establish cloud isolation foundations * feat(tenancy): harden shared cloud runtime boundaries * docs(tenancy): record final isolation verification * fix(tenancy): close isolation and permission gaps * docs(tenancy): record final isolation verification * feat(tenancy): connect cloud workspace control plane * fix(build): install git for pinned SDK * docs(cloud): update control plane verification * chore: update multi-tenant SDK pin * fix(cloud): skip legacy model sync during startup * test(cloud): preserve minimal model manager fixtures * fix(cloud): preserve authenticated account context * fix(cloud): reuse authenticated account for user info * feat(cloud): complete Workspace settings navigation * test(web): cover Workspace dropdown menu * feat(web): place workspace controls in sidebar * refactor(web): streamline workspace controls * style(web): format workspace layout test * fix(cloud): surface runtime and workspace plan status * fix(plugin): keep runtime identity stable across restarts * fix(ui): widen and center workspace switcher * fix(ui): hide roles from workspace switcher * fix(ui): align workspace switcher with sidebar entries * feat(workspace): add in-product collaboration and direct Cloud launch * style: format collaboration changes * fix(workspace): bind collaboration APIs to tenant UoW * fix(cloud): preserve Core-owned collaboration state * test(cloud): require Space identity for invite registration * feat(cloud): complete secure invitation experience * style(web): format invitation flows * fix(cloud): recover box runtime without unscoped skill reload * feat(oss): enforce invitation account and owner billing flows * style: format OSS account service * test(oss): cover invitation logout handoff * fix(oss): resolve workspace owner in scoped session * feat(cloud): harden multi-tenant runtime resources * fix(cloud): bound runtime restart storms * fix(cloud): eliminate periodic runtime CPU spikes * fix(cloud): enforce instance capacity ceilings * fix(cloud): scope public login capability discovery * fix(cloud): bound tenant maintenance and monitoring work * fix(runtime): bound tenant resource amplification * fix(deps): pin green multi-tenant plugin SDK * fix(cloud): handle unavailable skill capability * fix(security): require authentication for image file endpoint (H-2) - Changed /api/v1/files/image from AuthType.NONE to USER_TOKEN_OR_API_KEY - Added Permission.RESOURCE_VIEW requirement - Prevents unauthenticated cross-tenant file access via leaked keys - Fixes HIGH severity finding from multi-tenant security review docs: add comprehensive database migration guide - Complete migration steps for OSS → multi-tenant - Backup, execution, verification procedures - Rollback scenarios and recovery plans - Performance tuning recommendations * test: add comprehensive cross-tenant isolation tests Added 7 critical test scenarios for multi-tenant boundaries: - Cross-tenant bot access prevention - Viewer role read-only enforcement - Removed member immediate access revocation - Model provider credential isolation - WebSocket message isolation - Invitation token workspace scoping - Multi-workspace context validation These tests address P0-2 coverage gaps for: - workspaces.py (membership & invitation flows) - user.py (authentication & authorization) - websocket_chat.py (real-time isolation) - plugins.py (resource access control) docs: finalize database migration guide * fix(security): resolve M-1, M-2, M-3 security findings M-1: WebSocket authorization TOCTOU race (FIXED) - Changed _revalidate_websocket_authorization to return RequestContext - Ensures validated context is used immediately without race window - Prevents removed members from sending messages during revalidation gap M-2: Model Manager cache workspace isolation (VERIFIED) - Confirmed _CacheKey already uses 4-tuple: (instance, workspace, generation, resource) - Cache is properly scoped per workspace, no cross-tenant leakage possible - No code change needed, documented as working correctly M-3: Invitation lock workspace scoping (FIXED) - Changed lock key from token_digest to workspace_uuid:token_digest - Prevents DoS where attacker locks token in Workspace A to block Workspace B - Locks now isolated per workspace All MEDIUM severity findings from security review now resolved. * fix(cloud): unblock tenant CI and enforce knowledge quotas * fix(tenancy): scope rerank model sync --------- Co-authored-by: dadachann <185672915+dadachann@users.noreply.github.com>
4.2 KiB
name, description
| name | description |
|---|---|
| langbot-deploy | Deploy and configure a LangBot instance — Docker / Docker Compose, Kubernetes, the config.yaml model, the Box sandbox runtime, the plugin runtime, and the global API key. Use when installing, deploying, upgrading, or configuring LangBot in production or self-hosted environments. Triggers on "deploy langbot", "langbot docker", "langbot compose", "langbot kubernetes", "langbot config.yaml", "langbot box runtime", "langbot global api key". |
LangBot Deployment & Configuration
Covers running LangBot in production. For development see langbot-dev.
Docker Compose (recommended)
git clone https://github.com/langbot-app/LangBot
cd LangBot/docker
# Full stack (sandbox/Box + stdio MCP hosting + skill add/edit enabled)
docker compose --profile all up
# Basic (no Box runtime)
docker compose up
The all / box profile starts three services:
langbot— main app, serves API + UI on:5300.langbot_plugin_runtime— plugin runtime (control:5400, debug:5401).langbot_box— Box sandbox runtime (:5410). Uses the host Docker socket to spawn sandbox containers, so the Box root host path and in-container path must be identical (BOX__LOCAL__HOST_ROOT=${LANGBOT_BOX_ROOT:-${PWD}/data/box}). Its RPC and managed-process relay require a sharedLANGBOT_BOX_CONTROL_TOKEN(at least 32 non-whitespace characters) in both the LangBot and Box containers. Generate it once withopenssl rand -hex 32; never put it inbox.runtime.endpointor commit it to config.
Every Compose deployment also needs one
LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN shared by langbot and
langbot_plugin_runtime. Generate it with openssl rand -hex 32 and export it
before docker compose up; the external Plugin Runtime fails closed when the
token is empty or weak. Kubernetes uses the langbot-plugin-runtime-control
Secret shown in docker/kubernetes.yaml.
With Box off, the dashboard/skills list stays visible (read-only) but sandbox
tools, skill add/edit, and stdio MCP are disabled. Set box.enabled: false
(or BOX__ENABLED=false) to match.
Kubernetes
See docker/kubernetes.yaml and the deployment guide at
https://docs.langbot.app. docker/deploy-k8s-test.sh is a test helper.
config.yaml (generated at data/config.yaml on first run)
Top-level sections: api, system, command, concurrency, proxy,
database, vdb, storage, plugin, monitoring, box, space.
Key settings:
| Key | Meaning |
|---|---|
api.port |
HTTP API + UI port (default 5300) |
api.global_api_key |
Global API key for the HTTP API + MCP server. Non-empty = accepted with no login/DB record; no lbk_ prefix required. Empty = disabled. Plaintext — trusted/internal only, serve over HTTPS. |
plugin.runtime_ws_url |
Standalone plugin runtime WS URL (e.g. ws://langbot_plugin_runtime:5400/control/ws) |
box.enabled |
Master switch for the Box sandbox runtime |
box.backend |
local (Docker/nsjail autopick) / docker / nsjail / e2b; env override BOX__BACKEND |
box.runtime.endpoint |
External Box runtime URL (e.g. ws://127.0.0.1:5410); empty = local auto-managed |
Many keys have ENV__SUBKEY overrides (e.g. BOX__BACKEND, BOX__ENABLED).
Runtimes & flags
- LangBot started directly spawns the plugin runtime over stdio.
- In containers it connects to a standalone runtime over WebSocket; start
with
--standalone-runtime. - Box has a parallel
--standalone-boxflag; the Docker box host islangbot_box:5410.
Global API key — enabling for agents/automation
# data/config.yaml
api:
port: 5300
global_api_key: 'a-strong-secret' # empty disables it
This key authenticates both the HTTP API and the MCP server (/mcp) without a
login session. See langbot-mcp-ops for using it, and docs/API_KEY_AUTH.md.
Pitfalls
- "No supported sandbox backend (Docker / nsjail / E2B)" with Docker running
usually means the user isn't in the
dockergroup →sudo usermod -aG docker <user>and restart in a new shell. - Box root host/container path mismatch breaks sandbox container creation.
- Don't commit a non-empty
api.global_api_keyto version control.