Add a --trust-folder command-line argument to preload Workspace Trust - #328635
Add a --trust-folder command-line argument to preload Workspace Trust#328635Sean McManus (sean-mcmanus) wants to merge 8 commits into
Conversation
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.
There was a problem hiding this comment.
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. |
- 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.
📬 CODENOTIFYThe following users are being notified based on files changed in this PR: Robo (@deepak1556)Matched files:
|
There was a problem hiding this comment.
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
awaithere does not actually wait for the trust update to finish:setUrisTruststartsdoSetUrisTrust(...)without returning/awaiting its promise (line 660). If remote canonicalization of the CLI parent finishes before canonicalization of the workspace roots,addTrustedFoldersFromClicompletes andworkspaceTrustInitializedis resolved whileupdateWorkspaceTrust()is still waiting, so startup consumers can still observe the workspace as untrusted. MakesetUrisTrustawait/returndoSetUrisTrust(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.
getCanonicalUrionly consults the resolver whenenvironmentService.remoteAuthorityis 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.
There was a problem hiding this comment.
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.openEmptyWindowreusesenvironmentMainService.args(windowsMainService.ts:273-280), and window configuration inherits those args again (windowsMainService.ts:1529-1535). Treat--trust-folderas 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.
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.
|
Oops, I accidentally clicked the "Update branch" button -- I thought it was for a different PR. |
|
Jérémie Laval (@jeremie-stripe) Abry Rath (@abryrath) Sherry Shi (@sherryyshi) FruitSausage FYI, this PR fixes #126535 , which you had previously upvoted. |
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. avscode-remote://folder) and can be passed multiple times. It also shows in--help.Implements the feature requested in #126535.
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-trustisn't persisted — so every newly created workspace requires manually clicking through the Workspace Trust dialog each time.--trust-folderlets 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
--trust-folderoption (NativeParsedArgs['trust-folder']), shown in--help.IWorkbenchEnvironmentService.trustedFoldersexposes it (the native environment service reads the arg; web returns[]).WorkspaceTrustManagementServiceinitialization 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. Avscode-remote://folder is canonicalized after its matching remote authority resolves.combineUriFlags(incliArgs.ts, used bycli.ts) also rewrites--trust-folder <uri>into a single--flag=valuetoken, matching--folder-uri/--file-uri, so Chromium doesn't drop the URI value beforemain.jsruns.How to test
Open an otherwise-untrusted folder with the flag, using a clean
--user-data-dirso nothing is pre-trusted: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)
--trust-folder; with it the folder opens trusted; and it remains trusted after the flag is removed (persisted)..code-workspace): trusted when--trust-foldercovers a common parent of all roots (which also covers the.code-workspacefile); stays in Restricted Mode when only one root is passed. (For a saved multi-root workspace, every root folder and the.code-workspacefile'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 remotevscode-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-folderwhile 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:
--trust-folder ., or a URI form likefile:/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.windowsMainServiceonly 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).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.