* 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>
5.3 KiB
name, description
| name | description |
|---|---|
| langbot-dev | Develop, build, and debug the LangBot core backend and web frontend. Use when working inside the LangBot repository — backend (Python/Quart, src/langbot/pkg), the Vite/React web UI, HTTP API controllers/services, Alembic migrations, or the MCP server. Covers the dev environment (uv, pnpm), repo layout, the API auth model (user token / API key / global key), adding API endpoints, and the rule that API changes must update the MCP server and skills. Triggers on "langbot backend", "langbot dev", "langbot api", "add langbot endpoint", "langbot migration". |
LangBot Core Development
This skill covers developing the LangBot core (the main repo), distinct from
plugin development (see langbot-plugin-dev) and deployment (langbot-deploy).
Stack
- Backend: Python
>=3.11,<4.0, deps viauv. Framework: Quart (async Flask). Serves the HTTP API + pre-built web UI onhttp://127.0.0.1:5300. - Frontend (
web/): Vite + React Router 7 + shadcn/ui + Tailwind, managed bypnpm. Dev server on:3000. (NOT Next.js —devscript isvite.)
Dev environment
# Backend
pip install uv
uv sync --dev
uv run main.py # API + UI on http://127.0.0.1:5300
# Frontend (separate terminal)
cd web
cp .env.example .env
pnpm install
pnpm dev # http://127.0.0.1:3000 (reads VITE_API_BASE_URL)
# Lint/format hooks (CI runs the same checks)
uv run pre-commit install
First run generates data/config.yaml; DB defaults to SQLite (PostgreSQL
supported). Migrations run automatically on startup.
Repo layout (key paths)
src/langbot/
├── __main__.py # entrypoint, CLI flags (--standalone-runtime/-box/--debug)
├── pkg/
│ ├── api/
│ │ ├── http/ # Quart controllers + services
│ │ │ ├── controller/groups/ # route groups (@group.group_class)
│ │ │ └── service/ # business logic (called by controllers AND MCP)
│ │ └── mcp/ # MCP server (server.py = tools, mount.py = ASGI dispatch)
│ ├── core/ # app bootstrap, stages, task manager
│ ├── platform/ provider/ pipeline/ plugin/ box/ skill/ rag/ vector/
│ ├── command/ persistence/ storage/ config/ entity/ telemetry/
│ └── templates/config.yaml # config template (top-level: api, system, plugin, box, space...)
├── web/ # Vite SPA
└── docker/ # compose deployment
HTTP API auth model
Route auth is declared per-route via AuthType in
pkg/api/http/controller/group.py:
NONE— public.USER_TOKEN— web UI JWT (Authorization: Bearer <jwt>).API_KEY—X-API-KeyorAuthorization: Bearer <key>.USER_TOKEN_OR_API_KEY— either.
Authenticated routes receive an immutable RequestContext containing the
principal, authorized Workspace membership, fixed-role permissions, instance,
request id, and placement generation. A browser's X-Workspace-Id is only a
selector and is always checked against the Account membership. Tenant services
must accept this context (or an explicit trusted execution context) and fail
closed when it is absent.
API-key authentication accepts:
- the global key from
config.yamlapi.global_api_keyonly for a community instance with exactly one local Workspace, then - web-UI keys whose one-time
lbk_secret is stored only as a hash and is bound to one Workspace, explicit scopes, status, and optional expiry.
An API key derives its Workspace from the key record and ignores a caller's Workspace selector. Public Bot/Webhook routes similarly derive Workspace from the opaque owning resource rather than a header.
Route groups self-register via @group.group_class(name, path) and are
discovered by importutil.import_modules_in_pkg.
Adding an API endpoint
- Add/extend a controller in
pkg/api/http/controller/groups/and the matching service method inpkg/api/http/service/. - Pick the right
AuthType. - If the endpoint should be agent-accessible, add/adjust the matching MCP tool
in
pkg/api/mcp/server.pyand update thelangbot-mcp-opsskill. API and MCP surface must stay aligned (seeAGENTS.md). - Update
docs/service-api-openapi.jsonif you maintain the OpenAPI overview.
Database migrations (Alembic)
Single migration set supports SQLite + PostgreSQL. Files in
src/langbot/pkg/persistence/alembic/versions/.
# From project root (needs data/config.yaml)
uv run python -m langbot.pkg.persistence.alembic_runner autogenerate "description"
Standards
- All code comments/docstrings in English; user-facing strings need i18n
(
en_US+zh_Hansminimum,ja_JPwhere present). - Consider toC and toB compatibility + security.
- Commit format:
<type>(<scope>): <subject>(feat/fix/docs/refactor/...).
Tests
uv run pytest tests/unit_tests -q # unit tests
uv run pytest tests/unit_tests/api -q # API service tests
uv run python tests/manual/mcp_smoke.py # MCP server e2e smoke
See also
langbot-plugin-dev— plugin SDK / runtime development.langbot-testing— WebUI/e2e QA harness (bin/lbs).langbot-deploy— Docker/compose deployment + config.langbot-mcp-ops— operating the LangBot MCP server.