Thanks to visit codestin.com
Credit goes to github.com

Skip to content

User Approval Flow for Package Installation #136

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

Open
eleanorjboyd opened this issue Jan 23, 2025 · 16 comments
Open

User Approval Flow for Package Installation #136

eleanorjboyd opened this issue Jan 23, 2025 · 16 comments
Assignees
Labels
feature-request Request for new features or functionality needs spike
Milestone

Comments

@eleanorjboyd
Copy link
Member

Since this extension handles package installs, it should also correct communicate to the user about package installs and get user consent. The flow around package installs, user approval, when to allow background installs etc should be discussed and a plan outlined.

Security:

This is an important part of the user trust boundary as we should only have extensions install packages that have user consent. There could be different categories, trusted extensions that are allowed to install packages and untrusted extensions that need user consent to install.

Scenarios:

  • extension wants to install a package, it is not a pre-approved extension to install packages
  • extension wants to install a package, it is a pre-approved extension to install packages
  • user wants to reduce notifications and select to have packages installed in the background for a given extension
  • user wants to add, revoke, or edit which extensions can install / remove packages in a given workspace
  • user wants to add, revoke, or edit which extensions can install / remove packages at a user or more global level
  • user wants to accept installing a package without consenting to approve this extension going forward

Questions:

  • How do we make sure users are in control of the package installs while not making the experience too noisy?
  • Are there any extensions (like ones published by microsoft) that do not need to be prompted for the user to accept maybe only notified?
  • Do we still notify users on package install even if the installer is a pre-approved extension? Do users want to be notified every time?
@luabud
Copy link
Member

luabud commented Jan 25, 2025

I'm wondering if it'd make sense to have a setting which maps extensions with "approval" status? and by default, no extension is approved until a notification is displayed to the user asking for consent.
Then in hits notification they would have a choice to approve package(s) installation just this time, always approve package(s) installation for that extension, decline package(s) installation.

I don't think we should pre-approve any extension, even if it's from Microsoft. I don't think this would be too noisy, since I don't expect package installation to be something that common on a session, especially coming from different providers/extensions 🤔

@DonJayamanne
Copy link
Contributor

I don't think we should pre-approve any extension, even if it's from Microsoft

Agreed, in Jupyter extension we do the same
Data wrangler and synapse extensions execute code against a Jupyter kernel via the Jupyter extension API, here we have no special treatment for msft vs external extensions, same with Jupyter powertoys extension, which is managed by us as well,

@eleanorjboyd
Copy link
Member Author

eleanorjboyd commented Feb 3, 2025

hard to see sorry but began thinking of the flow, you can use mermaid.live to play around with it yourself

flowchart TD
    A["Install a Package"]

    C1["End: No changes needed"]
    A --> B{"Does the user have a config file?"}
    B -- "No" --> D1{"Create a new config file?"}
    B -- "Yes" --> E1{"Append to existing config?"}
    D1 -- "No" --> C1

    subgraph "Create New Config"
        D1 -- "Yes" --> D2["Prompt user for config type"] --> D3["Create config based on selection"] 
        
    end

    subgraph "Append to Existing Config"
        
        E1 -- "Yes" --> E2["Append settings"]
        E1 -- "User has >1 config file" --> E3["Prompt user to select config"] --> E2
    end
    E1 -- "No" --> C1
    D3 --> C1
    E2 --> C1
Image
flowchart TD
 subgraph subGraph0["User-Initiated Installation"]
        UI2["UI: User installs via extension manager"]
        UI3["AI Agent: User selects install after prompt"]
        UI6["User accepted extension installation"]
  end
 subgraph subGraph1["Background Installation"]
        BG1["AI Agent: Attempts to install via tool"]
        BG2["Extension: Attempts auto-install"]
        BG3["Notebook: JIT install attempt"]
  end
 subgraph subGraph2["Trust Flow"]
        T1{"Is the extension approved?"}
        T3{"Is pkg already installed?"}
        T4["Show notification"]
        T5@{ label: "Prompt: Approve, Trust, or Don't Install?" }
        T6["Update settings.json (Trust Extension)"]
  end
    UI2 --> A["Install Package"]
    UI3 --> A
    UI6 --> A
    BG1 --> A2["Trust Flow"]
    BG2 --> A2
    BG3 --> A2
    A2 --> T1
    T1 -- Yes --> A
    T1 -- No --> T3
    T3 -- yes --> T4
    T3 -- No --> T5
    T5 -- Don't Install --> T4
    T5 -- Approve This Install --> A
    T5 -- Trust This Extension --> T6
    T6 --> A

    T5@{ shape: diamond}
Image

@karthiknadig
Copy link
Member

Pylance Quickfix would probably use extension API so it would run into the same flow. For terminal CLI cases, I think, we can't control the flow.

@eleanorjboyd
Copy link
Member Author

If the user selects a quick fix then it would be a user-initiated install instead of a background one right? So Ill add two different types of extension API flows, ones that are user-initiated and ones that are background.

good point about terminal CLI- forgot about that aspect

@cwebster-99
Copy link
Member

Thanks for prepping this! I also wanted to mention @StellaHuang95 is looking into package install flows in the upcoming iteration from Pylance's perspective, so I would love to discuss ways in which this flow could be aided with info from Pylance since these will be complementary.

@eleanorjboyd
Copy link
Member Author

flowchart TD
 subgraph subGraph0["User-Initiated Installation"]
        UI2["UI: User installs via extension manager"]
        UI3["AI Agent: User selects install after prompt"]
        UI6["User accepted extension installation"]
  end
 subgraph subGraph1["Background Installation"]
        BG1["AI Agent: Attempts to install via tool"]
        BG2["Extension: Attempts auto-install"]
        BG3["Notebook: JIT install attempt"]
  end
 subgraph subGraph2["AllowInstalls Flow"]
        T1{"Is the extension approved?"}
        T3{"Is pkg already installed?"}
        T4["Show notification"]
        T5@{ label: "Quickpick: Approve Once, Approve ext always, or Don't Install?" }
        T6["Update settings.json (Trust Extension)"]
  end
    UI2 --> A["Install Package"]
    UI3 --> A
    UI6 --> A
    BG1 --> A2["AllowInstalls Flow"]
    BG2 --> A2
    BG3 --> A2
    A2 --> T1
    T1 -- Yes --> A
    T1 -- No --> T3
    T3 -- yes --> T4
    T3 -- No --> T5
    T5 -- Don't Install --> T4
    T5 -- Approve This Install --> A
    T5 -- Trust This Extension --> T6
    T6 --> A
Image
flowchart TD
    A["Install a Package"]

    C1["End of action"]
    A --> B{"Does the user have a config file? MVP only support requirements.txt"}
    B -- "No" --> D1{"Create a new config file?"}
    B -- "Yes" --> E1{"Append to existing config?"}
    D1 -- "No" --> C1

    subgraph "Create New Config"
        D1 -- "Yes" -->  D3["Create config based on selection"] 
        
    end

    subgraph "Append to Existing Config"
        
        E1 -- "Yes" --> E2["edit requirements.txt at root?"]
    end
    E1 -- "No" --> C1
    D3 --> C1
    E2 --> C1
Image

@eleanorjboyd
Copy link
Member Author

Outstanding questions:

  • How will settings.json look for saving user selection on pkg installation instructions
  • in the MVP thinking of only supporting requirements.txt and only 1 config file, so should this just be a requirements.txt at the root?
  • @karthiknadig thinks a quickpick is best for the dialog around install once, always install for ext, etc. What is the right wording this UI and how many options are there?

@eleanorjboyd
Copy link
Member Author

User initiated

given a user initiated the pkg install:
Image

Background Install

if an extension would like the install a pkg and has not gotten user permission yet:
Image

based on selection, go to either yes menu:
Image

or the no menu:
Image

@cwebster-99
Copy link
Member

cwebster-99 commented Feb 10, 2025

I might be able to provide more feedback on the flows above once I see it in action but a couple of initial thoughts:

  • User initiated: I think there is some cleaning up we can do on these user actions, I am a bit confused myself looking at these options so I imagine a user to also get tripped up. My POV is since this is user initiated, the options could be allow, allow but always ask, and block. Don't update the setting preferences and always ask seem to do the same thing based on how I am understanding it as of now. I think it gets a little confusing if we have some options that are related to one extension and some that are controlling this experience for any extension in one drop down.
  • I like the flow outlined on the background install where it is a bit more incremental.
  • I can see users not knowing the scope of a background install which would make them especially hesitant and how if differs from a user initiated flow based on what we are communicating here. With this in mind, I am unsure if a quick pick can effectively communicate the nuisance of the scenarios.

Could some of this flow be baked into setting up the default environment and package manager for a project? For example, could we set the "default" value for this to be "always ask" and then the user could go in and adjust this as desired.

Looking forward to seeing more of this flow!

@cwebster-99
Copy link
Member

cwebster-99 commented Feb 10, 2025

To ensure a shared understanding are the below definitions/examples correct:

  • user initiated = via a code action, within the install package option in the Python Envs side panel, etc.
  • background = JIT installs, Copilot tools/flows wanting to install a package, etc.

@eleanorjboyd
Copy link
Member Author

following quick chat with @cwebster-99 and @karthiknadig here are so new thoughts:

  • If the installation is by a environment manager inside the environment extension, the package gets installed. No additional displays to users
  • If the installation is called by an external extension through the package installation API, it will go through the following flow to help the user set their installation permissions for future actions by the given extension. The following is described in this mermaid chart
Image
flowchart LR
 subgraph s1["Environment Extension Barrier"]
        n1["API Call: Install Pkg"]
        n3["[internal]: install pkg<br>"]
        n5@{ label: "is ext 'alwaysAllow'?" }
        n6["User Dialog: Install this pkg?"]
        m5@{ label: "is ext 'alwaysPrompt'?" }
        n7["User Dialog: AlwaysAllow or AlwaysPrompt?"]
        n8["User Dialog: Block ext? Never show notif again?"]
        n9["Update settings"]
        m3@{ label: "is ext 'alwaysBlock?'" }
  end
    n2["external extension"] --> n1
    n1 --> m3
    n5 -- No --> n6
    n5 -- Yes --> n3
    n7 --> n9
    n8 --> n9
    m3 -- No --> n5
    m3 -- Yes --> n10["do nothing"]
    m5 -- Yes install & Yes alwaysPrompt --> n3
    m5 -- Yes install & No alwaysPrompt --> n7
    n6 -- "in parallel check..." --> m5
    m5 -- No install & No alwaysPrompt --> n8
    m5 -- No install & Yes alwaysPrompt --> n10

    n1@{ shape: event}
    n3@{ shape: rect}
    n5@{ shape: decision}
    n6@{ shape: manual-input}
    m5@{ shape: decision}
    n7@{ shape: manual-input}
    n8@{ shape: manual-input}
    n9@{ shape: manual-file}
    m3@{ shape: decision}
    n2@{ shape: hex}
    n10@{ shape: terminal}

@eleanorjboyd
Copy link
Member Author

apologize for the length this thread is getting but wanted to make sure it is up to date for those following along. New idea

Image
flowchart LR
 subgraph s1["Environment Extension Barrier"]
        n1["API Call: Install Pkg"]
        n3["[internal]: install pkg<br>"]
        n5@{ label: "is ext 'alwaysAllow'?" }
        n6["User Dialog: Install this pkg?"]
        m5@{ label: "is ext 'alwaysPrompt'?" }
        n7["User Dialog: AlwaysAllow or AlwaysPrompt?"]
        n9["Update settings"]
  end
    n2["external extension"] --> n1
    n5 -- No --> n6
    n5 -- Yes --> n3
    n7 --> n9
    m5 -- Yes install & Yes alwaysPrompt --> n3
    m5 -- Yes install & No alwaysPrompt --> n7
    n6 -- "in parallel check..." --> m5
    m5 -- No install --> n10["do nothing"]
    n1 --> n5

    n1@{ shape: event}
    n3@{ shape: rect}
    n5@{ shape: decision}
    n6@{ shape: manual-input}
    m5@{ shape: decision}
    n7@{ shape: manual-input}
    n9@{ shape: manual-file}
    n2@{ shape: hex}
    n10@{ shape: terminal}

@cwebster-99
Copy link
Member

I like where this is at - thanks for updating based on all the back and forth!

@karthiknadig karthiknadig added the feature-request Request for new features or functionality label Feb 12, 2025
@eleanorjboyd
Copy link
Member Author

eleanorjboyd commented Feb 12, 2025

@karthiknadig and I discussed and these were the two designs that came up for the settings

option A:

"python.environments.packagePermissions" : {
    "ms.python": "alwaysAllow",
    "ms.copilot": "alwaysAsk",
    "*": "alwaysAsk"
}

option B:

"python.environments.packagePermissions" : {
    "alwaysAllow": ["ms.python", "ms.pylance"],
    "alwaysPrompt": ["*"]
}

naming is also not determined so we need to get a setting name idea and what to call the different "alwaysAllow" and "alwaysAsk" settings.

we also discussed the default to the setting maybe being this based off which of these the user has installed
ms.python - alwaysAllow
ms.pylance - alwaysAllow
vscode.copilot - alwaysPrompt
everything else "*" - alwaysPrompt

(i would add ms.juptyer - alwaysAllow to the list)

@eleanorjboyd
Copy link
Member Author

Following more recent meetings, here is the new proposed plan:

  1. All settings around which extensions to trust will be stored in secret extension storage instead of a setting in the settings.json for security and privacy.
  2. There will be no wildcard settings for extensions, each extension will prompt the user, and each time the user will select their preference, no bulk approval at this point

The flow will be as follows:

To start (when first installing a pkg) the first menu will be shown to ANY extension that are not configured yet (ie the settings not saved in the secret storage)
MENU:
"Set permissions for this and future package installations from {extension-name}"
options:

  • "Always allow" - save this setting (and install pkg)
  • "Always ask"- save this setting (and install pkg)
  • "cancel" - do not configure and do not install pkg

Once an extension is saved into the secret storage with its package allow extension then menu is based on setting:
if extension is set to "always allow", do not show any menu, we could show a notification that it got installed
if extension is set to "always ask" show the following menu:
MENU
"{extName} wants to install '${packages}' packages"
options:

  • install
  • don't install

Finally there should be a way for a user to configure and look at their package installation setting stored in the secret settings. We should surface a menu or something where people can:

  • adjust existing levels for extensions
  • add new extensions and their package installation level.

see updated wording as it stands now in the newest additions to the PR: be528ee

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature-request Request for new features or functionality needs spike
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants