Skip to content

feat: enforce workspace trust in extension/plugin system#17098

Merged
eneufeld merged 4 commits intomasterfrom
fix/16890
Mar 17, 2026
Merged

feat: enforce workspace trust in extension/plugin system#17098
eneufeld merged 4 commits intomasterfrom
fix/16890

Conversation

@eneufeld
Copy link
Copy Markdown
Contributor

@eneufeld eneufeld commented Mar 2, 2026

What it does

Read capabilities.untrustedWorkspaces.supported from plugin manifests during scanning and store it on PluginModel. Extensions declaring supported: false are skipped during contribution loading when the workspace is untrusted, and their IDs surface in the restricted mode status bar indicator.

  • Add capabilities to PluginPackage and untrustedWorkspacesSupport to PluginModel
  • Extract applyTrustExtraction() helper in AbstractPluginScanner, used by both Theia and VS Code scanners
  • Filter untrusted plugins in AbstractHostedPluginSupport.loadContributions()
  • Register WorkspaceRestrictionContribution to show disabled extensions in the restricted mode tooltip
  • Remove redundant SCM trust workaround in PluginViewRegistry
  • Reload window on trust change to restart extension hosts

Fixes #16890

How to test

Start an untrusted workspace and see that eg the git plugin is not loaded anymore.

Follow-ups

Extensions with supported: 'limited' are currently loaded normally, same as true. The restrictedConfigurations mechanism is not implemented.

Breaking changes

  • This PR introduces breaking changes and requires careful review. If yes, the breaking changes section in the changelog has been updated.

Attribution

Review checklist

Reminder for reviewers

@eneufeld eneufeld requested a review from ndoschek March 2, 2026 10:11
@github-project-automation github-project-automation Bot moved this to Waiting on reviewers in PR Backlog Mar 2, 2026
Copy link
Copy Markdown
Member

@ndoschek ndoschek left a comment

Choose a reason for hiding this comment

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

Thank you @eneufeld for this PR!
Overall this looks good to me, just a few comments inline.
Also thanks for adding a range of tests 👍

Extensions that declare untrustedWorkspaces.supported: false should also be marked as disabled in the Extensions view while in restricted mode. We already have the functionality to mark extensions as disabled — currently they are silently skipped during contribution loading, but the user has no way to see why a specific extension isn't working unless they check the restricted mode status bar tooltip. Also fine as a follow-up if you prefer.

Image

One additional question: the PR description mentions "Remove redundant SCM trust workaround in PluginViewRegistry" but I don't see any changes to that file in the diff.

Comment on lines +179 to +180
this.windowService.setSafeToShutDown();
this.windowService.reload();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The hard reload in workspace-trust-service.ts changes the current workspace trust behavior and seems problematic. Calling setSafeToShutDown() + reload() directly in setWorkspaceTrust bypasses any unsaved-changes confirmation and forces a reload for every trust change, even if no extensions are actually affected.

More concerning: it looks like this blocks the settings persistence. When I trigger the trust change via the command, the reload happens before the trust setting save is finished, which causes a loop and the workspace might never actually becomes trusted because the setting doesn't persist across the reload.

Could you have another here please?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

IMHO App Reloads are Necessary:

  1. Plugin Trust Filtering Architecture

Untrusted plugins are filtered out during the initial plugin loading phase
When trust changes from false → true, previously filtered plugins need to be loaded
The plugin system doesn't support dynamic loading after initialization

  1. Current Reload Triggers:

Manual trust changes via setWorkspaceTrust()
Trusted folders preference changes
Workspace trust enabled/disabled preference changes

  1. Why Alternatives Are Not Viable:

Dynamic plugin loading: Very complex, plugin system not designed for it
Lazy activation: Security concerns and architectural complexity
Trust-aware architecture: Would require major system redesign

The current reload approach is:

✅ Safe: Ensures clean state without stale references
✅ Reliable: Well-tested pattern similar to VS Code
✅ Simple: Avoids complex plugin lifecycle management
✅ Appropriate: Trust changes are infrequent user actions

I will still check on how to improve the usability.

Comment thread packages/plugin-ext/src/hosted/common/hosted-plugin.ts Outdated
Comment thread packages/plugin-ext/src/hosted/common/hosted-plugin.ts Outdated
@github-project-automation github-project-automation Bot moved this from Waiting on reviewers to Waiting on author in PR Backlog Mar 6, 2026
eneufeld added 2 commits March 9, 2026 14:34
Read `capabilities.untrustedWorkspaces.supported` from plugin manifests
during scanning and store it on PluginModel. Extensions declaring
`supported: false` are skipped during contribution loading when the
workspace is untrusted, and their IDs surface in the restricted mode
status bar indicator.

- Add `capabilities` to PluginPackage and `untrustedWorkspacesSupport`
  to PluginModel
- Extract `applyTrustExtraction()` helper in AbstractPluginScanner,
  used by both Theia and VS Code scanners
- Filter untrusted plugins in
  AbstractHostedPluginSupport.loadContributions()
- Register WorkspaceRestrictionContribution to show disabled
  extensions in the restricted mode tooltip
- Remove redundant SCM trust workaround in PluginViewRegistry
- Reload window on trust change to restart extension hosts

Fixes #16890
@eneufeld
Copy link
Copy Markdown
Contributor Author

eneufeld commented Mar 9, 2026

@ndoschek
about the cleanup in pluginview registry,
the pr fixing welcome views to scm, adds two comments referencing:
See https://github.com/eclipse-theia/theia/issues/12318
these two comments need to be removed. either by this pr (that was initially the case as I did this after the other) or in the other pr

Copy link
Copy Markdown
Member

@ndoschek ndoschek left a comment

Choose a reason for hiding this comment

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

Thank you for the update @eneufeld!
The trust settings are now properly saved before the reload happens 👍

However, I still have 2 addtional comments:

  1. Still, I think we should make the user aware that a reload is about to happen. For other settings, we already have the reload confirmation dialog, for example for the title bar style change in the Electron example (see below). This way, the user can still decide whether the reload should happen immediately. I can see that we basically already have this confirmation dialog in the workspace trust service (this.confirmRestart()), although I do not see it appearing atm on a workspace trust change anymore.

    Image

    This is basically the same pattern as when disabling an extension manually.
    To make the disabled setting apply, the user has to reload. If they ignore it, it is their own decision.

    Image
  2. I think extensions that were installed manually during runtime also be disabled in restricted mode? Currently, manually installed extensions via the open vsx registry remain enabled, while the same extensions are disabled in VS Code when running in restricted mode. It might make sense to align this behavior.
    As example, I observed this with these installed extensions for example:

    • meganrogge.template-string-converter
    • tobermory.es6-string-html
    • vscjava.vscode-java-pack

    Also, we do not prompt the user in any way during the installation process of an extension while in restricted mode. We can also extract this into a follow up though.

    As reference, VS Code shows this dialog:
    Image

Comment thread packages/plugin-ext/src/main/browser/style/plugin-sidebar.css Outdated
Comment thread packages/vsx-registry/src/browser/vsx-extension.tsx Outdated
Comment thread packages/vsx-registry/src/browser/vsx-extension.tsx
@eneufeld eneufeld requested a review from ndoschek March 13, 2026 21:00
Copy link
Copy Markdown
Member

@ndoschek ndoschek left a comment

Choose a reason for hiding this comment

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

Thank you @eneufeld for the updates, LGTM and works very well for me now 👍

I just have a minor comment about the info message in restricted mode. Could you have a quick look wdyt, TIA

Comment thread packages/vsx-registry/src/browser/vsx-extension.tsx Outdated
Comment thread packages/vsx-registry/src/browser/vsx-extension.tsx Outdated
Comment thread sample-plugins/sample-namespace/plugin-a/package.json
Co-authored-by: Nina Doschek <ndoschek@eclipsesource.com>
Copy link
Copy Markdown
Member

@ndoschek ndoschek left a comment

Choose a reason for hiding this comment

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

Thank you @eneufeld for the updates, LGTM and works very well now for me! 🎉

@github-project-automation github-project-automation Bot moved this from Waiting on author to Needs merge in PR Backlog Mar 17, 2026
@eneufeld eneufeld merged commit 48a3f9b into master Mar 17, 2026
10 checks passed
@eneufeld eneufeld deleted the fix/16890 branch March 17, 2026 10:53
@github-project-automation github-project-automation Bot moved this from Needs merge to Done in PR Backlog Mar 17, 2026
@github-actions github-actions Bot added this to the 1.70.0 milestone Mar 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

Verify and enforce workspace trust in extension/plugin system

2 participants