Skip to content

Plugins: require explicit trust for workspace-discovered plugins#44174

Merged
vincentkoc merged 6 commits intomainfrom
vincentkoc-code/ghsa-99qw-workspace-plugin-trust
Mar 12, 2026
Merged

Plugins: require explicit trust for workspace-discovered plugins#44174
vincentkoc merged 6 commits intomainfrom
vincentkoc-code/ghsa-99qw-workspace-plugin-trust

Conversation

@vincentkoc
Copy link
Member

Summary

  • Problem: OpenClaw auto-discovered and default-enabled workspace plugins from .openclaw/extensions, so cloned repositories could execute plugin code without an explicit trust decision.
  • Why it matters: running the gateway inside an untrusted cloned repo could execute arbitrary workspace plugin code on the host.
  • What changed: workspace-discovered plugins are now disabled by default unless explicitly trusted through plugins.allow or a per-plugin enable entry.
  • What did NOT change (scope boundary): explicitly trusted workspace plugins still load, and non-workspace plugin trust behavior is unchanged.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

User-visible / Behavior Changes

Workspace-discovered plugins under .openclaw/extensions no longer auto-load by default. Operators must explicitly trust them with plugins.allow or an explicit plugin entry.

Security Impact (required)

  • New permissions/capabilities? (Yes/No) No
  • Secrets/tokens handling changed? (Yes/No) No
  • New/changed network calls? (Yes/No) No
  • Command/tool execution surface changed? (Yes/No) Yes
  • Data access scope changed? (Yes/No) Yes
  • If any Yes, explain risk + mitigation: the change reduces implicit command/data access by requiring an explicit trust decision before workspace plugin code can execute.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm
  • Model/provider: N/A
  • Integration/channel (if any): plugin loader
  • Relevant config (redacted): default plugins config with empty plugins.allow

Steps

  1. Create a temp workspace containing .openclaw/extensions/<id>/openclaw.plugin.json and index.ts with a side effect in register().
  2. Load plugins with loadOpenClawPlugins({ workspaceDir, config: {} }).
  3. Observe whether the workspace plugin is loaded automatically.

Expected

  • Workspace plugin is discovered but disabled until explicitly trusted.

Actual

  • With this patch, the workspace plugin is disabled by default and loads only when explicitly allowlisted.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: reproduced the pre-fix auto-load path with a temp workspace plugin; verified the patched branch disables it by default and still allows explicit trust via plugins.allow.
  • Edge cases checked: explicit per-plugin enable and explicit allowlist both preserve intended workspace plugin loading.
  • What you did not verify: full end-to-end gateway startup against every plugin origin.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No) No
  • Config/env changes? (Yes/No) No
  • Migration needed? (Yes/No) Maybe
  • If yes, exact upgrade steps: if you intentionally use workspace plugins, add their ids to plugins.allow or explicitly enable them in plugins.entries.

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert the branch or explicitly trust the affected workspace plugin.
  • Files/config to restore: src/plugins/config-state.ts
  • Known bad symptoms reviewers should watch for: intentionally used workspace plugins no longer loading until trusted.

Risks and Mitigations

  • Risk: operators relying on implicit workspace plugin loading will see plugins disabled after upgrade.
  • Mitigation: explicit allowlist and per-plugin enable paths continue to work, and tests cover both trust mechanisms.

@vincentkoc vincentkoc self-assigned this Mar 12, 2026
@openclaw-barnacle openclaw-barnacle bot added size: S maintainer Maintainer-authored PR labels Mar 12, 2026
@vincentkoc vincentkoc marked this pull request as ready for review March 12, 2026 15:59
@greptile-apps
Copy link
Contributor

greptile-apps bot commented Mar 12, 2026

Greptile Summary

This PR hardens workspace plugin trust by requiring an explicit opt-in before plugins discovered under .openclaw/extensions can execute. Previously, any cloned repository containing that directory could silently inject plugin code at gateway startup; now resolveEnableState treats origin === "workspace" as disabled by default, returning only when the plugin id appears in plugins.allow or has an explicit entries: { enabled: true } entry.

Key changes:

  • resolveEnableState in config-state.ts adds a workspace-origin guard after the deny/disable checks and after the per-entry explicit-enable check, correctly preventing auto-load while still honouring both explicit trust mechanisms.
  • Three new unit tests in config-state.test.ts cover the default-off, plugins.allow, and entries paths.
  • Two new integration tests in loader.test.ts cover end-to-end default-off and plugins.allow paths.

Minor observation: The entries: { enabled: true } trust path is validated only at the unit level (config-state.test.ts) and not exercised through the full loader pipeline in loader.test.ts. This is low risk — the allow-list integration test already confirms that resolveEnableState is wired correctly into the loader — but a matching integration test would close the gap entirely.

Confidence Score: 4/5

  • This PR is safe to merge; it reduces implicit execution surface with no regressions to explicitly-trusted plugin paths.
  • The logic change is small and targeted — one new branch in resolveEnableState with well-understood precedence relative to existing checks. All three trust paths (deny, allow, entries) are tested. The only gap is that the entries-based trust path lacks a loader-level integration test, which is low risk given the unit coverage and the fact that the loader integration test already validates resolveEnableState is wired correctly.
  • No files require special attention; src/plugins/config-state.ts is the only behavioural change and it is straightforward.

Last reviewed commit: cbc38be

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e0734a42c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@vincentkoc vincentkoc merged commit 3e28e10 into main Mar 12, 2026
29 checks passed
@vincentkoc vincentkoc deleted the vincentkoc-code/ghsa-99qw-workspace-plugin-trust branch March 12, 2026 16:12
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 623decefd3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +205 to +206
if (origin === "workspace" && !explicitlyAllowed && entry?.enabled !== true) {
return { enabled: false, reason: "workspace plugin (disabled by default)" };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Allow bundled fallback when workspace plugin is untrusted

This new workspace-default-disable branch turns untrusted workspace plugins into disabled records, but the loader still marks their IDs as seen (src/plugins/loader.ts:704-709), so later bundled candidates with the same ID are dropped as overridden by workspace plugin. Because discovery processes workspace before bundled (src/plugins/discovery.ts:689-710), a cloned repo can now disable built-in plugins (for example, telegram) just by shipping an untrusted .openclaw/extensions/<id> folder, leaving no plugin loaded for that ID; disabled workspace candidates should not shadow lower-precedence origins.

Useful? React with 👍 / 👎.

steipete pushed a commit to BruceMacD/openclaw that referenced this pull request Mar 13, 2026
…nclaw#44174)

* Plugins: disable implicit workspace plugin auto-load

* Tests: cover workspace plugin trust gating

* Changelog: note workspace plugin trust hardening

* Plugins: keep workspace trust gate ahead of memory slot defaults

* Tests: cover workspace memory-slot trust bypass
@HenryLoenwind
Copy link
Contributor

HenryLoenwind commented Mar 13, 2026

so cloned repositories

What is a "cloned repository" in your definition? .openclaw is the primary user-installation location. If the .openclaw folder is somehow put onto a system without the user's approval or trust, requiring a config ey from the config file that is also inside .openclaw is useless.

Can we please stop securing the software against the owning user?


Edit: And now I actually forgot to write what I followed the link in the changelog for...: This should be marked as BREAKING in the changelog.

dvrshil pushed a commit to JosepLee/openclaw that referenced this pull request Mar 14, 2026
…nclaw#44174)

* Plugins: disable implicit workspace plugin auto-load

* Tests: cover workspace plugin trust gating

* Changelog: note workspace plugin trust hardening

* Plugins: keep workspace trust gate ahead of memory slot defaults

* Tests: cover workspace memory-slot trust bypass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants