diff --git a/docs/automation/cron-jobs.md b/docs/automation/cron-jobs.md index e3bf42afdf0..e494d64e213 100644 --- a/docs/automation/cron-jobs.md +++ b/docs/automation/cron-jobs.md @@ -90,6 +90,8 @@ This fires ~5–6 times per month instead of 0–1 times per month. OpenClaw use For isolated jobs, runtime teardown now includes best-effort browser cleanup for that cron session. Cleanup failures are ignored so the actual cron result still wins. +Isolated cron runs also dispose any bundled MCP runtime instances created for the job through the shared runtime-cleanup path. This matches how main-session and custom-session MCP clients are torn down, so isolated cron jobs do not leak stdio child processes or long-lived MCP connections across runs. + When isolated cron runs orchestrate subagents, delivery also prefers the final descendant output over stale parent interim text. If descendants are still running, OpenClaw suppresses that partial parent update instead of announcing it. diff --git a/docs/channels/irc.md b/docs/channels/irc.md index 1eb04cd46a4..bd1d0396caa 100644 --- a/docs/channels/irc.md +++ b/docs/channels/irc.md @@ -237,6 +237,14 @@ Default account supports: - `IRC_NICKSERV_PASSWORD` - `IRC_NICKSERV_REGISTER_EMAIL` + +`IRC_HOST` is on the endpoint-block list and cannot be set from a workspace +`.env` file. It must come from shell environment or the gateway process +environment so that untrusted workspaces cannot redirect IRC traffic to a +different server. See [Workspace `.env` files](/gateway/security) for the full +list. + + ## Troubleshooting - If the bot connects but never replies in channels, verify `channels.irc.groups` **and** whether mention-gating is dropping messages (`missing-mention`). If you want it to reply without pings, set `requireMention:false` for the channel. diff --git a/docs/channels/matrix.md b/docs/channels/matrix.md index 80f275e2719..c2cf27f0648 100644 --- a/docs/channels/matrix.md +++ b/docs/channels/matrix.md @@ -179,6 +179,14 @@ For example, `-` becomes `_X2D_`, so `ops-prod` maps to `MATRIX_OPS_X2D_PROD_*`. The interactive wizard only offers the env-var shortcut when those auth env vars are already present and the selected account does not already have Matrix auth saved in config. + +`MATRIX_HOMESERVER` is on the endpoint-block list and cannot be set from a +workspace `.env` file. It must come from shell environment or the gateway +process environment so that untrusted workspaces cannot redirect Matrix +traffic to a different homeserver. See +[Workspace `.env` files](/gateway/security) for the full list. + + ## Configuration example This is a practical baseline config with DM pairing, room allowlist, and E2EE enabled: diff --git a/docs/channels/mattermost.md b/docs/channels/mattermost.md index e534f100e94..7bf3c3681e4 100644 --- a/docs/channels/mattermost.md +++ b/docs/channels/mattermost.md @@ -109,6 +109,14 @@ Set these on the gateway host if you prefer env vars: Env vars apply only to the **default** account (`default`). Other accounts must use config values. + +`MATTERMOST_URL` is on the endpoint-block list and cannot be set from a +workspace `.env` file. It must come from shell environment or the gateway +process environment so that untrusted workspaces cannot redirect Mattermost +traffic to a different server. See +[Workspace `.env` files](/gateway/security) for the full list. + + ## Chat modes Mattermost responds to DMs automatically. Channel behavior is controlled by `chatmode`: diff --git a/docs/channels/synology-chat.md b/docs/channels/synology-chat.md index 4194539dee8..b8928b1b031 100644 --- a/docs/channels/synology-chat.md +++ b/docs/channels/synology-chat.md @@ -89,6 +89,14 @@ For the default account, you can use env vars: Config values override env vars. + +`SYNOLOGY_CHAT_INCOMING_URL` is on the endpoint-block list and cannot be set +from a workspace `.env` file. It must come from shell environment or the +gateway process environment so that untrusted workspaces cannot redirect +Synology Chat traffic to a different webhook. See +[Workspace `.env` files](/gateway/security) for the full list. + + ## DM policy and access control - `dmPolicy: "allowlist"` is the recommended default. diff --git a/docs/cli/mcp.md b/docs/cli/mcp.md index 3c7459ab4b1..0cd19d5cb16 100644 --- a/docs/cli/mcp.md +++ b/docs/cli/mcp.md @@ -63,6 +63,12 @@ Important behavior: - older transcript history is read with `messages_read` - Claude push notifications only exist while the MCP session is alive - when the client disconnects, the bridge exits and the live queue is gone +- stdio MCP servers launched by OpenClaw (bundled or user-configured) are torn + down as a process tree on shutdown, so child subprocesses started by the + server do not survive after the parent stdio client exits +- deleting or resetting a session disposes that session's MCP clients through + the shared runtime cleanup path, so there are no lingering stdio connections + tied to a removed session ## Choose a client mode diff --git a/docs/plugins/architecture.md b/docs/plugins/architecture.md index 1d46d1abad8..987af3d4c71 100644 --- a/docs/plugins/architecture.md +++ b/docs/plugins/architecture.md @@ -478,6 +478,10 @@ Important trust note: - A workspace plugin with the same id as a bundled plugin intentionally shadows the bundled copy when that workspace plugin is enabled/allowlisted. - This is normal and useful for local development, patch testing, and hotfixes. +- Bundled-plugin trust is resolved from the source snapshot — the manifest and + code on disk at load time — rather than from install metadata. A corrupted + or substituted install record cannot silently widen a bundled plugin's trust + surface beyond what the actual source claims. ## Export boundary @@ -507,7 +511,9 @@ At startup, OpenClaw does roughly this: 4. normalize plugin config (`plugins.enabled`, `allow`, `deny`, `entries`, `slots`, `load.paths`) 5. decide enablement for each candidate -6. load enabled native modules via jiti +6. load enabled native modules — built `dist/*` bundled modules go through a + native loader path, while non-built native plugin modules are loaded via + jiti 7. call native `register(api)` (or `activate(api)` — a legacy alias) hooks and collect registrations into the plugin registry 8. expose the registry to commands/runtime surfaces diff --git a/docs/plugins/bundles.md b/docs/plugins/bundles.md index 166ac7a2c91..124b378b8f5 100644 --- a/docs/plugins/bundles.md +++ b/docs/plugins/bundles.md @@ -254,6 +254,18 @@ OpenClaw checks for native plugin format first: If a directory contains both, OpenClaw uses the native path. This prevents dual-format packages from being partially installed as bundles. +## Runtime dependencies and cleanup + +- Bundled plugin runtime dependencies ship inside the OpenClaw package under + `dist/*`. OpenClaw does **not** run `npm install` at startup for bundled + plugins; the release pipeline is responsible for shipping a complete bundled + dependency payload (see the postpublish verification rule in + [Releasing](/reference/RELEASING)). +- Sub-agent runs that launch bundled MCP servers dispose those MCP clients + through the shared runtime-cleanup path when the sub-agent exits, so + sub-agent lifecycles do not leak stdio child processes or long-lived MCP + connections across turns. + ## Security Bundles have a narrower trust boundary than native plugins: