Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Workspace Trust for Extension Authors #120251

Closed
sbatten opened this issue Mar 31, 2021 · 45 comments
Closed

Workspace Trust for Extension Authors #120251

sbatten opened this issue Mar 31, 2021 · 45 comments
Assignees
Labels
under-discussion Issue is under discussion for relevance, priority, approach workspace-trust Trusted workspaces
Milestone

Comments

@sbatten
Copy link
Member

sbatten commented Mar 31, 2021

This issue will be updated as information becomes available. Please subscribe and check back.

This issue will function as the landing page for extension authors while Workspace Trust is in development. If you are an extension author, please subscribe to this issue to receive notifications when the issue is updated.

Note that the feature has been in the works for some time now and we are nearing the phase where we would like extension authors to test it out and provide feedback. Once it is ready, we will post the extension authoring guide in this issue so that you can try adopting the new API.

To learn more about the development of the feature, check out our development issue: #106488

@sbatten
Copy link
Member Author

sbatten commented Apr 23, 2021

Workspace Trust Extension Guide

What is Workspace Trust?

Workspace Trust is a feature driven by the security risks associated with unintended code execution when a user opens a workspace in VS Code. For example, consider that a language extension, in order to provide functionality may execute code from the currently loaded workspace. In this scenario, the user should trust that the contents of the workspace are not malicious. Workspace Trust centralizes this decision within VS Code so that extension authors do not have to handle this themselves. VS Code will offer static declaration and API support to onboard extensions quickly without the need to duplicate code across extensions.

Onboarding

Static Declarations

In your extension's package.json, VS Code will support the following new property:

capabilities:
	untrustedWorkspaces:
		{ supported: true } |
		{ supported: false, description: string } |
		{ supported: 'limited', description: string, restrictedConfigurations?: string[] }

For the supported property, the following values are accepted:

  • true - The extension is fully supported in an untrusted workspace as it does not need workspace trust to perform any functionality. It will be enabled exactly as before.
  • false - The extension is not supported in an untrusted worskpace as it cannot function without workspace trust. It will remain disabled until workspace trust is granted.
  • 'limited' - Some features of the extension are supported in an untrusted workspace. Trust-sensitive features should be disabled until workspace trust is granted. The extension can use our API to hide or disable these features. Workspace settings can be gated by trust automatically using the restrictedConfigurations property.

For the description property, a description of why trust is needed must be provided to help the user understand what features will be disabled or what they should review before granting or denying workspace trust. If supported is set to true, this property is ignored.

💡The value for the description property should be added to package.nls.json and then referenced in the package.json file for localisation support.

For the restrictedConfigurations property, an array of configuration settings IDs are provided. When provided, the extension will not be given workspace-defined values for the given settings in an untrusted workspace.

How do I decide how my extension should support untrusted workspaces?

To help extension authors understand what is in scope for Workspace Trust, we have created a list of questions to consider.

Does my extension have a main entry point?

If the extension does not have a main entry point (ex: themes, language grammars), the extensions does not require workspace trust. Extension authors do not need to take any action for such extensions as they will continue to function independent whether the workspace is trusted or not.

Does my extension rely on files in the opened workspace to provide features?

This can mean things like settings that can be set by the workspace or actual code in the workspace. If the extension never uses any of the contents of the workspace, it probably doesn't require trust. Otherwise, take a look at the other questions.

Does my extension treat any contents of the workspace as code?

The most common example of this is using a project's workspace dependencies, such as the node modules stored in the local workspace. A malicious workspace might check in a compromised version of the module. Thus, this is a security risk for the user and extension. Auxiliary to this, an extension may rely on JavaScript or other configuration files that control the extension or other modules' behavior. However, many other examples could occur, such as executing an opened code file to determine its output a error reporting.

Does my extension use settings that can be defined in the workspace in any code execution?

Your extension might use settings values as flags to a CLI that your extension executes. If these settings are overridden by a malicious workspace, they could be used as an attack vector against your extension. On the other hand, if the settings' values are only used to detect certain conditions, (e.g. if the value of a preferred shell setting is bash or pwsh determines what documentation you show), then it may not be a security risk and does not require Workspace Trust. Below is a section dedicated to guidance on settings to help you find the optimal configuration for your extension.

This is not an exhaustive list of cases that might require Workspace Trust. As we review more extensions, we will update this list. Use this list to think of similar behavior your extension might be doing when considering Workspace Trust.

What if I don't make changes to my extension?

As mentioned above, an extension that does not contribute anything to their package.json will be treated as not supporting untrusted workspaces. It will be disabled when the workspace is not trusted and the user will be notified that some extensions are not working due to Workspace Trust. This measure is the most security-conscious approach for the user. Even though this is the default, it is still a best practice to set the appropriate value indicating that as an extension author, you have made the effort to protect the user and your extension from malicious workspace content.

How do I use the API?

As described above, the first step to using the API is adding the static declarations to your package.json. The easiest method of onboarding would be to use a false value for the supported property. Once again, this is the default behavior even if you do nothing, but it's a great signal to the user that you have made a deliberate choice. In this case, your extension does not need to do anything else. It will simply not be activated until trust is given and your extension can know that it is executing with the consent of the user. However, if your extension only requires trust for part of its functionality, this is likely not the best option.

For extensions that wish to gate their features on Workspace Trust, they should use the limited value for the supported property, and we provide the following API:

export namespace workspace {
	/**
		* When true, the user has explicitly trusted the contents of the workspace.
		*/
	export const isTrusted: boolean;

	/**
		* Event that fires when the current workspace has been trusted.
		*/
	export const onDidGrantWorkspaceTrust: Event<void>;
}

We provide a property to determine if the current workspace is trusted and an event for listening to when trust has been granted to the workspace. You can use these block specific code paths and perform any necessary registrations once the workspace has been trusted.

We also expose a context key isWorkspaceTrusted for use in when clauses as described below.

What about my contributions?

Commands, Views, or other UI

When the user has not trusted the workspace, they will operating in a mode with functionality geared towards browsing code. Any features that you provide that will not be trusted should be hidden from the user. This can be done via when clauses and the context key isWorkspaceTrusted. Since code can still call a command even if it is not presented in the UI, you should still block execution or not register a command based on the API above in your extension code.

Configurations/Settings

First, you should review your settings to determine if they need to take trust into account. As described above, a workspace may define a value for a setting that your extension consumes that is malicious to the use. If you identify settings that are vulnerable, you should use 'limited' for the supported property and list the setting ID in the restrictedConfigurations array.

When you add a setting ID to the restrictedConfigurations array, VS Code will only return the user-defined value of the setting in an untrusted workspace. This means your extension needs no additional code changes to handle the setting. When trust is granted, a configuration change event will fire in addition to the workspace trust event.

What is the guidance for debug extensions?

VS Code will prevent debugging in an untrusted workspace. For this reason, generally, debugging extensions do not need to additionally require trust and should select true for the supported property. However, if your extension provides additional functionality, commands, or settings that are not part of the built-in debugging flow, you should use 'limited' and the above guidance.

What is the guidance for task providers?

Similar to debugging, VS Code will prevent running tasks in an untrusted workspace. If your extension provides additional functionality, commands, or settings that are not part of the built-in tasks flow, you should use 'limited' and the above guidance. Otherwise, you can specify true.

How do I test Workspace Trust?

Please see this issue for current details on development of Workspace Trust. It should be up to date with how the feature is currently enabled.

@sbatten
Copy link
Member Author

sbatten commented Apr 23, 2021

For those subscribed, we are now ready to share the API and guidance for onboarding to workspace trust for extension authors. This is the first time sharing the guidance to a broader audience so please post questions here and we can update it for clarity. Thanks for your engagement.

@gjsjohnmurray
Copy link
Contributor

Is Workspace Trust going to land in the upcoming release?

@sbatten
Copy link
Member Author

sbatten commented Apr 23, 2021

The setting to enable the feature will remain disabled by default in the upcoming release

@RandomFractals
Copy link

@sbatten thank you for providing guidance on how trusted workspaces would work.

I am concerned about your default behaviour and my expectations would be that extensions that provide web views, side bar views, pseudo terminals and commands you can run in terminal, and work with workspace files, would still function as before when this feature is released.

I would rather see this feature as opt-in for extensions that want to be enabled for trusted workspaces, and work as before for untrusted workspaces. I think the behavior you describe is the opposite.

What if I don't make changes to my extension?

As mentioned above, an extension that does not contribute anything to their package.json will be treated as not supporting untrusted workspaces. It will be disabled when the workspace is not trusted and the user will be notified that some extensions are not working due to Workspace Trust. This measure is the most security-conscious approach for the user. Even though this is the default, it is still a best practice to set the appropriate value indicating that as an extension author, you have made the effort to protect the user and your extension from malicious workspace content.

@firelizzard18
Copy link

@sbatten Is there a way to prompt the user, "To enable this feature, you must trust the workspace"? For extensions that provide actions a user can execute, simply hiding (and disabling) that functionality may be bad UX. For example, the ESLint extension - at the moment - will prompt the user to execute ./node_modules/.bin/eslint if it is present, saying something like "Do you trust this?" How should that be updated for Workspace Trust? As I read your explanation, the extension should silently disable that functionality for untrusted workspaces. As a user, I would prefer a prompt - "The extension eslint wants to do <some thing> that requires you to trust this workspace - continue?"

As another example, I have an extension that provides code lenses for profiling benchmarks (CPU/memory use). If I hide these code lenses in untrusted workspaces, I'm sure someone will report that as a bug ("the benchmark code lens doesn't show up for my workspace"). I'd like the API to include something like this:

export namespace workspace {
    export function shouldExecuteActionRequiringTrust(description: string, alertOnFailure: bool, details?: string): Promise<bool>
}

If the workspace is not yet trusted and has not yet been prompted, this would show a prompt asking if the user wants to trust the workspace. If the workspace is untrusted and alertOnFailure is true, this would show a notification that, " cannot execute because the workspace is not trusted".

@sbatten
Copy link
Member Author

sbatten commented Apr 27, 2021

@RandomFractals @firelizzard18 Thanks for your engagement.

@RandomFractals you are correct in your understanding of the behavior. It is indeed opt-out, not opt-in. As this is a security feature, we must make the security-conscious decision to disable extensions that execute code and do not tell us about their trust support. We provide a user setting to override whether an extension supports untrusted workspaces locally to unblock users that have extensions that are slow to adopt. This puts the control in the hands of the user and is safe by default.

@firelizzard18 We hear this feedback. It is something we considered when coming up with the current strategy and we will keep our ears to ground on its necessity. With our current UX, we attempt to guide the user into one of two modes of operation, and they must make an explicit choice. In this way, we market the restricted mode for code browsing and navigation, but not active development since active development typically requires execution and thus trust.

We anticipate that a majority of users workflows are with trusted folders and thus should not choose restricted mode to do active development.

For this reason, the guidance is:

  • If you cannot provide a coherent browsing experience in an untrusted workspace, simply set your support value to false and rely on Code to indicate that features are disabled due to this choice.
  • If you can provide a solid experience for the restricted mode scenario, do so with limited or true.

@RandomFractals
Copy link

RandomFractals commented Apr 27, 2021

@sbatten thanks for your follow up. Sounds like the default behavior has already been decided on. I get why you'd want to configure extension activation and execution this way from security standpoint for untrusted workspaces.

What concerns me most about this approach is that it will create a potential stream of updates and some rework for extension developers similar to how we had to scramble and handle webview resources last year. I can also see a lot of users filing issues in extensions related to this new feature if configuration of this functionality is not well exposed in vscode UI for extensions and documented when you release it.

we must make the security-conscious decision to disable extensions that execute code and do not tell us about their trust support. We provide a user setting to override whether an extension supports untrusted workspaces locally to unblock users that have extensions that are slow to adopt. This puts the control in the hands of the user and is safe by default.

That part sounds like it might be ok, if you also provides proper prompts and notifications when switching between trusted and untrested workspaces.

I am not sure if @eamodio still does his monthly extension developers calls, but I think it would be great if we could do one for this functionality and you show us the whole flow of how it functions, and we hear other extension developers provide feedback that way before you realease this feature. There are only a few devs who expressed interest in learning more about this feature. So, should be manageable to get a few devs on a call for ext. devs review.

@PEZ
Copy link
Contributor

PEZ commented Apr 28, 2021

Hello, thanks for providing this information and way to follow as we prepare for the roll-out.

Can you paste some screenshots showing the user facing part of it? It would help me understand what choices I make as an extension developer.

@m-hilgendorf
Copy link

How do trusted workspaces impact language servers that are not implemented directly as vscode extensions? Will their clients require configuration to receive file change updates over LSP in untrusted workspaces?

@RandomFractals
Copy link

RandomFractals commented Apr 28, 2021

@rebornix how do new notebooks, custom kernels, code cells, and custom notebook renderers function in these new utrunsted workspaces??? They do execute code from cells :)

@brettcannon
Copy link
Member

@m-hilgendorf I think the security mechanism here is if your extension doesn't load then VS Code won't even have an opportunity to launch your language server or run any code of yours to connect to an externally started language server.

@RandomFractals the extensions providing notebook support will very likely simply not load in an untrusted workspace, so there won't be anything available to execute the cells.

@sbatten
Copy link
Member Author

sbatten commented Apr 28, 2021

@RandomFractals you can check out notebooks and workspace trust updates here #118584

@PEZ Since we are still polishing the UX pieces, I recommend you checkout the latest in VS Code Insiders by enabling the feature with security.workspace.trust.enabled in settings. To help you know where to look, you can expect a few components:

  • A dialog on startup when opening a new untrusted folder
  • An indicator in the status bar of the restricted mode (we are exploring more obvious UX currently)
  • A workspace trust settings editor with lots of context, accessible via the Gear icon or clicking the status bar entry

@m-hilgendorf Without any onboarding, these extensions won't activate and thus don't have any vulnerabilities. @TylerLeonhardt has locally onboarded the powershell extension to demo how extensions using LSP could onboard. I think he can provide more details.

@RandomFractals
Copy link

super! will try that setting in insiders and run a test Rest Book to see where we at. Thanks for the pointer to the untrusted notebooks and workspaces thread.

@RandomFractals
Copy link

@sbatten am I doing this right? seems to have no effect.

image

@sbatten
Copy link
Member Author

sbatten commented Apr 29, 2021

@RandomFractals That setting should be set to true in order to enable workspace trust (it turns on the feature but does not mean anything is trusted). It should require a restart to apply.

@RandomFractals
Copy link

RandomFractals commented Apr 29, 2021

tried it. do I need to actually check out and build the latest insiders v.? I set it to true, and still seeing that setting greyed out in settings.json, i.e. my insiders v. doesn't recognize it as a valid setting, and no prompts on reload.

my insiders v. info:

image

@PEZ
Copy link
Contributor

PEZ commented Apr 29, 2021

@RandomFractals, it needs to be configured in User settings.

justinmk3 pushed a commit to aws/aws-toolkit-vscode that referenced this issue Jun 21, 2021
VS code 1.57 introduced a 'trust' feature that is applied to the current workspace, restricting extension access based on trust level. The insiders build allows individual extensions to have a trust level, by default they are untrusted. Untrusted extensions cannot be activated, thus failing the test. We are not particularly concerned with this functionality in regards to other extensions, so we will just disable it entirely when testing.

We should look into this more for our own extension as far as UX is concerned (what should our extension be capable of given a minimum trust level?)

ref: microsoft/vscode#120251

Considerations for the toolkit (to be added to `package.json`):
```javascript
capabilities:
	untrustedWorkspaces:
		{ supported: true } |
		{ supported: false, description: string } |
		{ supported: 'limited', description: string, restrictedConfigurations?: string[] }
```
By default, extensions do not support untrusted workspaces. This seems to be the best option for the toolkit for now. In other words, we do not need to update anything unless we want to add a `description` string for why we do not support untrusted workspaces.
@lszomoru lszomoru modified the milestones: June 2021, July 2021 Jun 28, 2021
@dummdidumm
Copy link

I maintain a VS Code extension which has a setting which is currently marked with "scope": "application", meaning it can't be overwritten at the workspace level. Is there a way to lift this restriction for people who use newer versions of VS Code which mark the workspace as trusted while maintaining backwards-compatibility for older versions of VS Code in the sense of "keep "scope": "application""? I want to avoid bumping the minimum required VS Code version for the extension.

@sandy081
Copy link
Member

sandy081 commented Jul 7, 2021

I do not think there is a way other than bumping vscode engine version.

@sbatten sbatten modified the milestones: July 2021, Backlog Jul 12, 2021
@sbatten sbatten added the under-discussion Issue is under discussion for relevance, priority, approach label Jul 12, 2021
@vadimcn
Copy link
Contributor

vadimcn commented Jul 27, 2021

@sbatten What is the motivation behind asking debug extensions to mark themselves as safe for untrusted workspaces?
Debugging untrusted code is among the least safe things one could do. Wouldn't it make more sense to mark debug extensions as not supported for untrusted workspaces, just to be double-sure?

@bwateratmsft
Copy link
Contributor

@sbatten What is the motivation behind asking debug extensions to mark themselves as safe for untrusted workspaces?
Debugging untrusted code is among the least safe things one could do. Wouldn't it make more sense to mark debug extensions as not supported for untrusted workspaces, just to be double-sure?

@vadimcn I think that's covered already. From the description in this comment:

What is the guidance for debug extensions?

VS Code will prevent debugging in an untrusted workspace. For this reason, generally, debugging extensions do not need to additionally require trust and should select true for the supported property. However, if your extension provides additional functionality, commands, or settings that are not part of the built-in debugging flow, you should use 'limited' and the above guidance.

So I don't think debug extensions will be able to debug in an untrusted workspace, no matter what they mark themselves for.

@vadimcn
Copy link
Contributor

vadimcn commented Jul 28, 2021

Yes, I've seen that comment. I still don't understand the motivation for asking debug extensions to set "supported": true. Is there any behavioral difference between this and "supported": false?

@bwateratmsft
Copy link
Contributor

That makes sense. I think it will have to be up to extension authors to determine based on the guidance above. If the only thing an extension provides is debugging, I think that is functionally equivalent to "supported": false, but there could be other features that are safe in an untrusted workspace (or features that aren't, and "supported": "limited" is appropriate).

atscott added a commit to atscott/vscode-ng-language-service that referenced this issue Jun 9, 2022
…limited'

The workspace trust guide for extension authors can be found here:
microsoft/vscode#120251

Importantly the sectino for evaluating whether the extension should work
in an untrusted workspace asks "Does my extension treat any contents of the workspace as code?".
The answer to this is "yes" for the extension because we execute `ngcc`
from the `node_modules` folder. However, this isn't always necessary and
becomes less so with time. As library authors publish their libraries
with Ivy instructions, we will not need to run `ngcc`.

This commit updates the workspace trust to indicate that it's 'limited'
support due to `ngcc`. In addition the command to run `ngcc` is disabled
on the server and removed from the command palette.
atscott added a commit to atscott/vscode-ng-language-service that referenced this issue Jun 9, 2022
…limited'

The workspace trust guide for extension authors can be found here:
microsoft/vscode#120251

Importantly the sectino for evaluating whether the extension should work
in an untrusted workspace asks "Does my extension treat any contents of the workspace as code?".
The answer to this is "yes" for the extension because we execute `ngcc`
from the `node_modules` folder. However, this isn't always necessary and
becomes less so with time. As library authors publish their libraries
with Ivy instructions, we will not need to run `ngcc`.

This commit updates the workspace trust to indicate that it's 'limited'
support due to `ngcc`. In addition the command to run `ngcc` is disabled
on the server and removed from the command palette.
atscott added a commit to atscott/vscode-ng-language-service that referenced this issue Jun 9, 2022
…limited'

The workspace trust guide for extension authors can be found here:
microsoft/vscode#120251

Importantly the sectino for evaluating whether the extension should work
in an untrusted workspace asks "Does my extension treat any contents of the workspace as code?".
The answer to this is "yes" for the extension because we execute `ngcc`
from the `node_modules` folder. However, this isn't always necessary and
becomes less so with time. As library authors publish their libraries
with Ivy instructions, we will not need to run `ngcc`.

This commit updates the workspace trust to indicate that it's 'limited'
support due to `ngcc`. In addition the command to run `ngcc` is disabled
on the server and removed from the command palette.
atscott added a commit to atscott/vscode-ng-language-service that referenced this issue Jun 13, 2022
…limited'

The workspace trust guide for extension authors can be found here:
microsoft/vscode#120251

Importantly the sectino for evaluating whether the extension should work
in an untrusted workspace asks "Does my extension treat any contents of the workspace as code?".
The answer to this is "yes" for the extension because we execute `ngcc`
from the `node_modules` folder. However, this isn't always necessary and
becomes less so with time. As library authors publish their libraries
with Ivy instructions, we will not need to run `ngcc`.

This commit updates the workspace trust to indicate that it's 'limited'
support due to `ngcc`. In addition the command to run `ngcc` is disabled
on the server and removed from the command palette.
atscott added a commit to angular/vscode-ng-language-service that referenced this issue Jun 13, 2022
…limited' (#1695)

The workspace trust guide for extension authors can be found here:
microsoft/vscode#120251

Importantly the sectino for evaluating whether the extension should work
in an untrusted workspace asks "Does my extension treat any contents of the workspace as code?".
The answer to this is "yes" for the extension because we execute `ngcc`
from the `node_modules` folder. However, this isn't always necessary and
becomes less so with time. As library authors publish their libraries
with Ivy instructions, we will not need to run `ngcc`.

This commit updates the workspace trust to indicate that it's 'limited'
support due to `ngcc`. In addition the command to run `ngcc` is disabled
on the server and removed from the command palette.
@lszomoru lszomoru closed this as completed Dec 7, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Jan 31, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
under-discussion Issue is under discussion for relevance, priority, approach workspace-trust Trusted workspaces
Projects
None yet
Development

No branches or pull requests