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

Investigate what it means to support the notion of trust for virtual workspaces #126913

Open
sbatten opened this issue Jun 22, 2021 · 6 comments
Open
Assignees
Labels
under-discussion Issue is under discussion for relevance, priority, approach workspace-trust Trusted workspaces
Milestone

Comments

@sbatten
Copy link
Member

sbatten commented Jun 22, 2021

Started with this PR. However, I'm going to move some of the discussion and thinking to this issue.

Start with Resolver API

When creating Workspace Trust, we needed a solution for handling URIs in remote windows. e.g. Dev Containers open local folders within dev containers that then have strange workspace URIs the user was asked to trust separately. To improve the user experience, we introduced the canonical URI api for resolvers.

/**
* Get the canonical URI (if applicable) for a `vscode-remote://` URI.
*
* @returns The canonical URI or undefined if the uri is already canonical.
*/
getCanonicalURI?(uri: Uri): ProviderResult<Uri>;

The purpose of this API is to allow each resolver to provide us with a re-usable URI that we can trust. In the Dev Container example, this can be mapped to a local file path. WSL could do the same when it makes sense. Codespaces could (but does not) remap the URI to a GitHub https URI.

Considering RemoteHub

After introducing this API to the limited set of resolvers, we saw a similar need for RemoteHub which happened to be a file system provider. RemoteHub already had internally a re-mapping exactly like the resolver API but no way to provide it to core. Hence, we created the PR to introduce the same API to file system providers. Before releasing Workspace Trust, we could not take this API so late, and there were too many file system providers out in the wild that might conflict with workspace trust so we decided to handle RemoteHub in core and avoid the conflict with other virtual file system providers.

Concerns with the File System Provider API

  1. We are duplicating the API. This is true; however, currently resolvers work quite differently than file system providers in when they are loaded. For resolvers, we need to handle the URI transformation prior to resolution of the workspace which in turn means prior to loading other extensions. We might be able to skirt this requirement in file system providers.

  2. The name of the API is confusing in a File System Provider. It does not make it clear the purpose of this API. The API is very specifically needed only for Workspace Trust and doesn't serve much other purpose. It is also not a traditional FS-type API.

  3. If we do want to remap the URIs of File System Providers prior to activating extensions, we need some rethinking. Separating this API into something that can be loaded early is worth exploring.

Updated Proposal

Rename the API to something workspace trust specific. e.g. WorkspaceTrustUriProvider with a function getTrustableUri(uri) or getUriAlias(uri). These would be registered to a given scheme (not the file scheme). We could consider additional restrictions e.g. only for schemes your extension registers other providers for, only one provider per scheme, etc.

Example Extensions

RemoteHub

RemoteHub is the de-factor virtual workspace provider today. It allows you to connect to a GitHub repo without cloning. It would like to convert vscode-vfs URIs to https URIs.

GitLens

GitLens doesn't exactly provide a complete workspace but adds folders to a workspace when browsing an open repository at a specific commit. It would like to convert gitlens URIs to local file URIs.

Docker

Docker allows you to browse and open files from a running container. The most secure approach would probably be to treat these as loose files that are not trusted.

Kubernetes

Based on my understanding of the extension, this is similar to Docker.

GitHub PRI

The virtual file system is intended to browse issues and does not seem to pose any risk.

Azure Databases

The file system provides a way to update cosmos db items. It isn't a full workspace but you can open editors with contents. However, practically, this is not a security risk and you don't typically connect to arbitrary cosmos dbs.

SSH FS

I haven't tested the URI structure, but this one would likely mimic a blend of SSH remote + RemoteHub giving a readable URI to trust and edit.

Remote FS

Works with sftp or ftp to provide virtual file system. I doubt any remapping would be necessary, but a proper implementation would require trust.

Gist Pad

Allows opening arbitrary gists on GitHub. Opening them is similar to RemoteHub except it follows more of a loose file flow. I would expect to be able to trust https uris.

Zip FS

I would expect this to resolve URIs to the local paths which really means just changing the scheme.

DEV Community

This extension auths into dev.to communities allowing you to edit posts. Due to the auth step here, and them being your posts, I don't expect a trust prompt.

@sbatten sbatten self-assigned this Jun 22, 2021
@sbatten sbatten added this to the June 2021 milestone Jun 22, 2021
@sbatten sbatten added the workspace-trust Trusted workspaces label Jun 24, 2021
@alexdima
Copy link
Member

This is quite difficult. What we do for resolvers is IMHO not doable in general. Resolvers activate before the vscode API is fully functional. So various things do not work by design. Resolvers have been like that since day 1 and they are prepared for that. While resolving, they don’t exercise those unavailable APIs or have workarounds in place. IMHO we cannot take any extension and activate it so early, as that would cause unforeseen bugs since the API has holes.

IMHO such a method would still belong to the FS provider. For example, suppose both extension A and extension B register the same schema hello: and only extension B registers the proposed workspace trust provider. I’m not 100% certain how the FS provider API behaves, maybe it is possible that due to activation ordering or interleaved execution, that FS provider from A gets to “win”, so the hello: FS is serviced by extension A. But if there is a distinct workspace trust provider API, it is possible that we will end up in the situation where extension B provides the trust aliases for files that are serviced by extension A by accident. So this hints strongly to me that the correct thing to do in order to make sure the same extension drives both the trust provider API and the FS provider API is to register these two APIs together, either as an option or as a method of the FS provider.

I’m also not sure what you’d want from the extension host infrastructure… If I understand FS providers correctly, they can come in 20minutes after a window is up and running, via user gestures (e.g. suppose there is a FS provider that is used to implement jump to definition). When the user jumps to definition, they end up with the first time with a csharp-def: URI and this could lead to the activation of an extension that defines that FS provider. So however you want this to work, IMHO this needs to work at any time in the extension host lifecycle, not just when things start up. I think computing trust for a given URI must become async, and be implemented by awaiting the activation event onFileSystem:X and then checking if the FS provider was registered together with a trust URI provider and then calling that.

cc @jrieken

@jrieken
Copy link
Member

jrieken commented Jun 25, 2021

When the user jumps to definition, they end up with the first time with a csharp-def: URI and this could lead to the activation of an extension that defines that FS provider

That's a good sample because these lightweight things are usually not file system providers but just document content provider. Is that something that also needs to be enrolled in trust and also need to support uri aliasing?

But if there is a distinct workspace trust provider API, it is possible that we will end up in the situation where extension B provides the trust aliases for files that are serviced by extension A by accident

I see where you are coming wrong but in a way it's also desirable to decouple trusted workspaces from file system provider. Assume, I use a simple SSH file system, like https://marketplace.visualstudio.com/items?itemName=Kelvin.vscode-sshfs, why should it bother and how would it know that some.machine is actually localhost. Isn't that the job of whom opens the workspace?

@sbatten
Copy link
Member Author

sbatten commented Jun 25, 2021

So however you want this to work, IMHO this needs to work at any time in the extension host lifecycle, not just when things start up.

The non-startup case is much less of an issue for us. At that point, we have the luxury of everything being available for us to await on. The query trust API for a specific URI is already async so we could await the providers registration if we know its coming.

The startup case is primarily important for file system providers that provide workspace contents (i.e. a workspace uri belongs to its scheme) and gets dicey because our current startup flow (which tells us the startup value of workspace trust) likes to finish before all extensions are loaded.

After that, if workspace uris change, we await the necessary information before updating the trust state and firing off the event.

That's a good sample because these lightweight things are usually not file system providers but just document content provider. Is that something that also needs to be enrolled in trust and also need to support uri aliasing?

Practically, this is usually no because the content seems to be either related or depended upon by the existing workspace. So, in most cases, you expect to trust to match the open workspaces.

why should it bother and how would it know that some.machine is actually localhost. Isn't that the job of whom opens the workspace?

I'm not sure I understand where this question is leading. For the sshfs extension, I believe its paths should be considered during trust calculations because it is very similar to the ssh remote scenario. I wouldn't expect it or a user to care about remapping the uris to localhost if that were the case, just having a reusable trustable uri: sshfs://machinename/path/to/trusted. Their scheme may already be in a trustable format, but they do need a way to tell us that the uris should be considered in the calculation.

@lszomoru lszomoru modified the milestones: June 2021, July 2021 Jun 28, 2021
@sbatten sbatten added the under-discussion Issue is under discussion for relevance, priority, approach label Jun 30, 2021
@jrieken
Copy link
Member

jrieken commented Jun 30, 2021

Practically, this is usually no because the content seems to be either related or depended upon by the existing workspace. So, in most cases, you expect to trust to match the open workspaces.

That means theoretically yes? To some extend file system providers and virtual document providers are very similar. E.g said sample of csharp-def file is often (and historically) virtual documents but can be implemented with a readonly file system. So, providing a file system doesn't mean that you provide a workspace but file system providers can be used to provide workspace folders. Sorry to ask again but what problem are we trying to solve? Is this about trusting workspace folders that are backed by file system providers or any virtual file/document?

@sbatten
Copy link
Member Author

sbatten commented Jun 30, 2021

There are indeed 2 types of items that could require trust and you list them there:

  1. Virtual Workspace Folders
  2. Virtual Files or Documents

While in a perfect world we handled both of these with great UX, the second one can be a lot trickier due to the ways we allow that to happen and the variety of virtual documents that might have nothing to do with trust.

Workspace Folders are much more obviously related to workspace trust and we have our own extensions that would like to take advantage of some API.

So solving both would be great, but I wouldn't want to get hung up on 2 if it makes things awful when 1 is much more immediately relevant.

@AnrDaemon
Copy link

Is this still actual or in for a 🔒 ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
under-discussion Issue is under discussion for relevance, priority, approach workspace-trust Trusted workspaces
Projects
None yet
Development

No branches or pull requests

5 participants