6.1 KiB
Multi-tenant verification report
Date: 2026-07-19
This report records the implementation and verification evidence for the Core Workspace isolation kernel. It does not claim that the closed SaaS Control Plane or Cloud v2 deployment is production-ready.
Repository refs and scope
- LangBot branch:
feat/multi-tenants - LangBot implementation commit:
c6f826fe2d2e12cc73479155e8f25566048c1c56 - LangBot base:
origin/masterat6baeb032a7f76c65337b51c7b58593de4687a61c - Plugin SDK branch:
feat/multi-tenants - Plugin SDK commit and LangBot dependency pin:
a1544b6b38a37ba72e3284f2836618144f0742c1 - Space remained on
mainat5058b039c2629e3b01ebd7358369b50e7df62a1c, with no tracked changes made by this implementation.
The SDK protocol is versioned as 0.4.15 but is intentionally consumed from the exact pushed Git commit on this feature branch. Publishing 0.4.15 and replacing the Git pin with a registry pin remain merge-to-master release steps.
Automated verification
LangBot backend
.venv/bin/ruff check .
passed
changed and untracked Python format check
220 files already formatted
.venv/bin/pytest tests/unit_tests -q
2051 passed, 1 skipped, 110 warnings in 26.87s
.venv/bin/pytest tests/integration -q
163 passed, 19 skipped, 28 warnings in 6.00s
uvx --from uv@latest uv lock --check
resolved 277 packages; passed
git diff --check
passed
Database migrations
- Fresh and upgraded SQLite schemas passed, including verified pre-boundary backups, forced-failure restore, retry, and revision manifest checks.
- A disposable PostgreSQL 16 instance exercised fresh and upgraded tenancy
migrations:
9 passed, 9 warnings in 8.57s. - Alembic has one head,
0010_scope_resources, through the chain0008_mcp_resource_prefs -> 0009_workspace_tenancy -> 0010_scope_resources. - ORM-to-migration coverage found no missing tenant table.
Plugin SDK and runtime
SDK full test suite
1029 passed, 18 warnings in 8.20s
SDK Ruff and action consistency checks
passed
Docker-backed Box integration tests
13 passed
The SDK remote branch and LangBot Git dependency were both resolved and verified at the same commit recorded above.
Frontend
pnpm lint
0 errors, 34 warnings
pnpm build
passed; 3167 modules
pnpm exec playwright test --project=chromium
40 passed in 19.9s
Bot form initialization race pressure test
10 passed in 9.4s
The browser suite covers singleton bootstrap, explicit multi-Workspace selection under the test policy, selector headers, account-state cleanup, Workspace switching, and invitation terminal-state recovery.
Packaging and deployment configuration
- Docker Compose with Plugin Runtime and Box control tokens passed
docker compose ... --profile all config --quiet. - Compose, Kubernetes, and the default configuration passed YAML parsing.
- Kubernetes selector, volume, and control-token reference checks passed.
skills/bin/lbs index --checkandskills/bin/lbs validatepassed.- The staged secret scan found no committed credential; test-token literals were confirmed to be non-secret fixtures.
Real browser E2E
The bundled production web application and backend were started against a clean, temporary SQLite data directory. The following flows were performed in the in-app browser against the real API rather than mocks:
- The first Account registered and became owner of the automatically created singleton Workspace.
- The owner created a one-time invitation link.
- A signed-out second Account inspected the fragment-based invitation, registered, accepted it, and entered the Workspace as viewer.
- The same member was cycled through viewer, operator, developer, admin, and owner. Visible controls matched the backend permission matrix, including owner transfer only for an owner.
- A viewer invitation mutation returned 403
permission_denied; an owner attempt to create a second OSS Workspace returned 403edition_limit. - Owner/member account switching, refresh, and a newly opened browser tab recovered only the active Account and singleton Workspace state.
- Used, revoked, expired, and email-mismatched invitation states rendered distinct errors. Terminal tokens were cleared, while the mismatch flow allowed switching to the intended Account.
- With the plugin system disabled,
/api/v1/pluginsand/api/v1/system/status/plugin-systemboth returned 200 after a clean server restart. The only remaining browser console error was the expected failure to reach the optional external Space release feed.
The test server was stopped, port 15321 was verified free, and the temporary test directory was moved to the system Trash. Multi-Workspace same-name and same-identifier isolation is exercised by the automated test-only Cloud policy; the OSS browser cannot create a second Workspace by design.
Final audit
The final isolation audit found no remaining P0/P1 tenant isolation issue in the OSS singleton-Workspace, multi-user scope. Focused checks also covered the plugin-disabled Workspace fence, invitation fragment/account-switch behavior, and the Bot form initialization sequence. Unrelated untracked workspace files were excluded from both commits.
Deliberately incomplete SaaS gates
Multi-Workspace activation remains unavailable in the open-source bootstrap. Cloud v2 must remain disabled until the following closed-system gates are implemented and independently verified:
- signed
InstanceManifestverification and closedCloudWorkspacePolicyinjection; - authoritative Account, Workspace, Membership, Invitation, placement, entitlement, usage, subscription, and billing services;
- generation-aware database transaction and outbox fences through commit;
- stable durable object references across placement-generation cutovers;
- atomic shared OAuth-state and directory-projection stores;
- tenant-safe egress and SSRF enforcement for all configurable outbound URLs;
- a greenfield Cloud v2 deployment, without carrying forward the legacy Space deployment model.
These are release gates, not hidden fallbacks. Mutable Core configuration or an edition flag cannot enable SaaS multi-tenancy.