feat(tenancy): implement workspace isolation

This commit is contained in:
Junyan Qin
2026-07-19 09:58:59 +08:00
parent 9eb292992d
commit c6f826fe2d
271 changed files with 31162 additions and 6106 deletions
+18 -2
View File
@@ -14,6 +14,9 @@ services:
restart: on-failure
environment:
- TZ=Asia/Shanghai
# Shared with the langbot service and sent only as a WebSocket handshake
# header. Generate with: openssl rand -hex 32
- LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN=${LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN:-}
command: ["uv", "run", "--no-sync", "-m", "langbot_plugin.cli.__init__", "rt"]
networks:
- langbot_network
@@ -40,9 +43,16 @@ services:
restart: on-failure
environment:
- TZ=Asia/Shanghai
# Shared control-plane secret used to authenticate both the RPC socket
# and managed-process relay. Generate once (for example with
# ``openssl rand -hex 32``) and export it before enabling this profile.
# An empty value is accepted by Compose so Box can remain optional, but
# the Box runtime itself fails closed when the profile is started.
- LANGBOT_BOX_CONTROL_TOKEN=${LANGBOT_BOX_CONTROL_TOKEN:-}
# The Box runtime does NOT read box.local.* from config.yaml or env; it
# receives its configuration from LangBot via the INIT RPC action.
# Do not add LANGBOT_BOX_* / BOX__* here — they would be silently ignored.
# receives its functional configuration from LangBot via the INIT RPC
# action. LANGBOT_BOX_CONTROL_TOKEN is the intentional security-only
# exception; do not add BOX__* here because those would be ignored.
# Launched through the same CLI entry point as the plugin runtime
# (`langbot_plugin.cli.__init__ <subcommand>`). WebSocket is the default
# control transport — mirrors `rt`, which also runs with no flag. Pass
@@ -60,6 +70,12 @@ services:
restart: on-failure
environment:
- TZ=Asia/Shanghai
# Must match langbot_plugin_runtime. Empty/missing values make the
# external control channel fail closed.
- LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN=${LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN:-}
# Must match the value supplied to langbot_box. The token is sent only
# in WebSocket handshake headers, never in URLs or action payloads.
- LANGBOT_BOX_CONTROL_TOKEN=${LANGBOT_BOX_CONTROL_TOKEN:-}
# Unified env-override convention: SECTION__SUBSECTION__KEY overrides the
# matching config.yaml field (see LoadConfigStage). These map onto
# box.* and are forwarded to the Box runtime via INIT RPC.
+28 -2
View File
@@ -4,6 +4,10 @@
# Full deployment guide (zh/en/ja): https://docs.langbot.app -> Installation -> Kubernetes
#
# Usage:
# kubectl -n langbot create secret generic langbot-plugin-runtime-control \
# --from-literal=token="$(openssl rand -hex 32)"
# kubectl -n langbot create secret generic langbot-box-control \
# --from-literal=token="$(openssl rand -hex 32)"
# kubectl apply -f kubernetes.yaml
#
# Prerequisites:
@@ -127,6 +131,11 @@ spec:
configMapKeyRef:
name: langbot-config
key: TZ
- name: LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN
valueFrom:
secretKeyRef:
name: langbot-plugin-runtime-control
key: token
volumeMounts:
- name: plugin-data
mountPath: /app/data/plugins
@@ -246,9 +255,14 @@ spec:
configMapKeyRef:
name: langbot-config
key: TZ
- name: LANGBOT_BOX_CONTROL_TOKEN
valueFrom:
secretKeyRef:
name: langbot-box-control
key: token
# The Box runtime does NOT read box.local.* / BOX__* from its own env;
# it receives its configuration from LangBot via the INIT RPC action.
# Do not add BOX__* here — they would be silently ignored.
# it receives its functional configuration from LangBot via INIT.
# LANGBOT_BOX_CONTROL_TOKEN is the security-only exception.
volumeMounts:
# Box workspace root — identical path on node, box, and sandbox
# containers (see the IMPORTANT note above).
@@ -352,6 +366,11 @@ spec:
configMapKeyRef:
name: langbot-config
key: PLUGIN__RUNTIME_WS_URL
- name: LANGBOT_PLUGIN_RUNTIME_CONTROL_TOKEN
valueFrom:
secretKeyRef:
name: langbot-plugin-runtime-control
key: token
# Box (sandbox) runtime endpoint. Connects LangBot to the langbot-box
# Service over WebSocket. Remove this (and the langbot-box Deployment)
# and set BOX__ENABLED=false if you do not want the sandbox.
@@ -360,6 +379,13 @@ spec:
configMapKeyRef:
name: langbot-config
key: BOX__RUNTIME__ENDPOINT
# Same Secret as langbot-box. It authenticates the RPC and managed-
# process relay handshakes and is never put in a URL or RPC payload.
- name: LANGBOT_BOX_CONTROL_TOKEN
valueFrom:
secretKeyRef:
name: langbot-box-control
key: token
# box.local.* config — forwarded to the Box runtime via INIT RPC. The
# host_root MUST match the box-root hostPath mountPath below AND the box
# Deployment's box-root mountPath, so that skill package paths resolve