Skip to content

Add a --trust-folder command-line argument to preload Workspace Trust - #328635

Open
Sean McManus (sean-mcmanus) wants to merge 8 commits into
microsoft:mainfrom
sean-mcmanus:seanmcm/devbox2-wsl/agent1/add-trust-folder
Open

Add a --trust-folder command-line argument to preload Workspace Trust#328635
Sean McManus (sean-mcmanus) wants to merge 8 commits into
microsoft:mainfrom
sean-mcmanus:seanmcm/devbox2-wsl/agent1/add-trust-folder

Conversation

@sean-mcmanus

@sean-mcmanus Sean McManus (sean-mcmanus) commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a --trust-folder <path|uri> command-line argument that marks the given folder(s) as trusted for Workspace Trust before the window opens, and persists them to the trusted-folder list so they stay trusted on later opens (unlike --disable-workspace-trust, which is per-launch and not persisted). The value accepts a local path or a URI (e.g. a vscode-remote:// folder) and can be passed multiple times. It also shows in --help.

Implements the feature requested in #126535.

This PR was investigated and created by Copilot with Claude Opus 4.8 (in VS Code). Any PR review responses starting with ✨ Copilot says: were auto-generated by Copilot. UPDATE: Later iterations switched to GPT-5.6 Sol starting August 4th.

Motivation

I use a script that creates and fully sets up a fresh git-worktree workspace, each in its own new "agent" folder near the filesystem root. Because every workspace lives in its own top-level folder, there is no shared parent folder I can pre-trust, and --disable-workspace-trust isn't persisted — so every newly created workspace requires manually clicking through the Workspace Trust dialog each time. --trust-folder lets the setup script mark the new folder trusted up front (persisted), so the workspace opens trusted without any clicks.

There is currently no supported non-UI way to trust a specific folder — the trusted-folder list is intentionally kept out of settings for security. A command-line argument is outside the workspace's control, so it does not reintroduce that concern.

Changes

  • New repeatable --trust-folder option (NativeParsedArgs['trust-folder']), shown in --help.
  • IWorkbenchEnvironmentService.trustedFolders exposes it (the native environment service reads the arg; web returns []).
  • During WorkspaceTrustManagementService initialization each folder is canonicalized and persisted independently, and the resulting trust transition is awaited before Workspace Trust is signalled as initialized, so the workspace is already trusted at startup with no prompt. A vscode-remote:// folder is canonicalized after its matching remote authority resolves.
  • The flag is a one-shot launch request: the initial window receives it, then it is removed from both the shared process arguments and the configuration reused by Reload Window, so later windows and reloads cannot reapply trust after the user revokes it. A later CLI invocation carries and applies its own parsed arguments normally.
  • On Windows, combineUriFlags (in cliArgs.ts, used by cli.ts) also rewrites --trust-folder <uri> into a single --flag=value token, matching --folder-uri/--file-uri, so Chromium doesn't drop the URI value before main.js runs.

How to test

Open an otherwise-untrusted folder with the flag, using a clean --user-data-dir so nothing is pre-trusted:

mkdir -p /tmp/trust-test
./scripts/code.sh --user-data-dir /tmp/vscode-trust-test --trust-folder /tmp/trust-test /tmp/trust-test

The folder opens Trusted (no dialog/banner, no Restricted Mode). Reopen it without the flag (same --user-data-dir) and it stays Trusted — confirming persistence.

Manually verified (by Sean, not Copilot)

  • Single folder: the trust prompt reproduces without --trust-folder; with it the folder opens trusted; and it remains trusted after the flag is removed (persisted).
  • Multi-root workspace (.code-workspace): trusted when --trust-folder covers a common parent of all roots (which also covers the .code-workspace file); stays in Restricted Mode when only one root is passed. (For a saved multi-root workspace, every root folder and the .code-workspace file's location must be covered — trusting a common parent is simplest.)

Covered by unit tests

  • workspaceTrust.test.ts: single folder; subfolder of a trusted parent; multiple folders; multi-root workspace (all roots vs only some trusted); a remote vscode-remote:// folder; a value that fails to canonicalize not discarding the others; initialization waiting for persistence and the trust transition; an empty list; a malformed value (ignored); and persistence across a reload.
  • argv.test.ts: the initial-window argument snapshot retains --trust-folder while shared process arguments and reload configurations consume it.
  • cliArgs.test.ts: --trust-folder <uri> is combined into --flag=value (the Windows argv path).

Known limitations

These are deferred as fail-safe follow-ups. In each case the worst outcome is that a folder is simply not trusted and the user gets the normal Workspace Trust prompt (Restricted Mode) — there is no path to unwanted or escalated trust, so they err toward less trust, not more:

  • Relative / non-canonical CLI values (e.g. --trust-folder ., or a URI form like file:/tmp/x): the value is classified (path vs. URI) and resolved in the workbench rather than normalized against the invoking CLI's working directory in the main process, so a value that doesn't resolve to the intended folder just won't match and the folder stays untrusted. A complete fix normalizes non-URI values against the caller's cwd and classifies URI schemes during main-process argument validation, where the cwd is still available.
  • Flag ignored when the target window is already open: trust is applied during workbench startup, so if the folder/workspace is already open windowsMainService only focuses the existing window and the flag has no effect that launch. A complete fix routes the request to the existing window (or persists it in the main process).
  • Remote URIs for a different or not-yet-connected authority: a vscode-remote:// value is resolver-canonicalized only when its authority matches the window's active remote authority. Preloading a remote URI from a local window, or passing values for multiple remote authorities, may persist a raw URI that does not match the workspace URI after that authority's resolver canonicalizes it later. A complete fix re-canonicalizes matching stored entries when their resolver becomes available; until then the workspace remains untrusted.

Adds a repeatable --trust-folder <path|uri> argument that marks the given folder(s) as trusted before the window opens and persists them, so a workspace can be opened trusted without going through the trust dialog.

Implements microsoft#126535.
Copilot AI review requested due to automatic review settings August 2, 2026 21:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds a repeatable --trust-folder CLI option that preloads and persists Workspace Trust entries.

Changes:

  • Registers and exposes trusted-folder arguments.
  • Persists local and remote trusted folders during trust initialization.
  • Adds Workspace Trust coverage for core scenarios.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/vs/platform/environment/common/argv.ts Defines the parsed argument.
src/vs/platform/environment/node/argv.ts Registers CLI help and parsing.
src/vs/platform/environment/common/environmentService.ts Exposes native argument values.
src/vs/workbench/services/environment/common/environmentService.ts Adds the workbench contract.
src/vs/workbench/services/environment/browser/environmentService.ts Provides the web fallback.
src/vs/workbench/services/workspaces/common/workspaceTrust.ts Canonicalizes and persists CLI trust entries.
src/vs/workbench/services/workspaces/test/common/workspaceTrust.test.ts Tests trust and persistence scenarios.

Comment thread src/vs/platform/environment/node/argv.ts
Comment thread src/vs/workbench/services/workspaces/common/workspaceTrust.ts Outdated
Comment thread src/vs/workbench/services/workspaces/common/workspaceTrust.ts Outdated
Comment thread src/vs/workbench/services/workspaces/common/workspaceTrust.ts
@sean-mcmanus
Sean McManus (sean-mcmanus) marked this pull request as draft August 2, 2026 21:48
- combineUriFlags now rewrites --trust-folder <uri> so Windows does not drop the value before main.js runs.
- addTrustedFoldersFromCli trusts each folder independently so one value that cannot be resolved no longer discards the other valid entries.
- Adds unit tests for both.
@sean-mcmanus
Sean McManus (sean-mcmanus) marked this pull request as ready for review August 2, 2026 22:18
@vs-code-engineering

vs-code-engineering Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

📬 CODENOTIFY

The following users are being notified based on files changed in this PR:

Robo (@deepak1556)

Matched files:

  • src/vs/code/electron-main/app.ts
  • src/vs/code/node/cliArgs.ts
  • src/vs/code/test/node/cliArgs.test.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/vs/workbench/services/workspaces/common/workspaceTrust.ts:310

  • await here does not actually wait for the trust update to finish: setUrisTrust starts doSetUrisTrust(...) without returning/awaiting its promise (line 660). If remote canonicalization of the CLI parent finishes before canonicalization of the workspace roots, addTrustedFoldersFromCli completes and workspaceTrustInitialized is resolved while updateWorkspaceTrust() is still waiting, so startup consumers can still observe the workspace as untrusted. Make setUrisTrust await/return doSetUrisTrust (and add a test with delayed workspace canonicalization) before using its completion to signal initialization.
				await this.setUrisTrust([uri], true);

src/vs/workbench/services/workspaces/common/workspaceTrust.ts:301

  • Remote entries are only canonicalized when this window is already connected to the matching authority. getCanonicalUri only consults the resolver when environmentService.remoteAuthority is set, and the native canonical-URI provider returns an unchanged URI for any other authority (nativeExtensionService.ts:361-365). Therefore preloading a remote URI from a local window—or repeating remote folders from different authorities—persists a raw URI that may not match the resolver-canonicalized workspace URI later. Canonicalize matching stored entries when their authority becomes available, or otherwise route each remote entry through its resolver before persisting it.

This issue also appears on line 310 of the same file.

				// A value with a scheme (e.g. a remote `vscode-remote://` folder) is
				// parsed as a URI; otherwise it is treated as a local file path.
				uri = folder.includes('://') ? URI.parse(folder) : URI.file(folder);

Return only after trusted URI persistence and workspace trust transitions finish, so workspaceTrustInitialized cannot resolve early. Add a regression test that stalls the transition and verifies initialization remains pending.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 9 out of 9 changed files in this pull request and generated no new comments.

Suppressed comments (1)

src/vs/workbench/services/workspaces/common/workspaceTrust.ts:291

  • This reprocesses the launch argument in every subsequently created window, so a folder that the user explicitly removes from the trusted-folders UI is silently trusted again on File > New Window. windowsMainService.openEmptyWindow reuses environmentMainService.args (windowsMainService.ts:273-280), and window configuration inherits those args again (windowsMainService.ts:1529-1535). Treat --trust-folder as a one-shot request—consume it in the main process or remove it from inherited args after routing it to the launch window—so later windows cannot undo an explicit trust revocation.
	private async addTrustedFoldersFromCli(): Promise<void> {
		const folders = this.environmentService.trustedFolders;

Copy the initial process arguments for the startup window, then remove the one-shot trust request from the shared arguments inherited by later windows. Secondary CLI launches continue to carry their own parsed arguments. Add a focused unit test for the consumption contract.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.

Comment thread src/vs/platform/environment/common/argv.ts Outdated
Remove one-shot window arguments from the configuration reused by Reload Window while retaining them for the initial load. Extend the focused argument test to cover both process inheritance and reload reuse.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated no new comments.

@sean-mcmanus

Copy link
Copy Markdown
Contributor Author

Oops, I accidentally clicked the "Update branch" button -- I thought it was for a different PR.

@sean-mcmanus

Copy link
Copy Markdown
Contributor Author

Jérémie Laval (@jeremie-stripe) Abry Rath (@abryrath) Sherry Shi (@sherryyshi) FruitSausage FYI, this PR fixes #126535 , which you had previously upvoted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants