Introduce worktree trust mechanism (#44887)
Closes https://github.com/zed-industries/zed/issues/12589 Forces Zed to require user permissions before running any basic potentially dangerous actions: parsing and synchronizing `.zed/settings.json`, downloading and spawning any language and MCP servers (includes `prettier` and `copilot` instances) and all `NodeRuntime` interactions. There are more we can add later, among the ideas: DAP downloads on debugger start, Python virtual environment, etc. By default, Zed starts in restricted mode and shows a `! Restricted Mode` in the title bar, no aforementioned actions are executed. Clicking it or calling `workspace::ToggleWorktreeSecurity` command will bring a modal to trust worktrees or dismiss the modal: <img width="1341" height="475" alt="1" src="https://github.com/user-attachments/assets/4fabe63a-6494-42c7-b0ea-606abb1c0c20" /> Agent Panel shows a message too: <img width="644" height="106" alt="2" src="https://github.com/user-attachments/assets/0a4554bc-1f1e-455b-b97d-244d7d6a3259" /> This works on local, SSH and WSL remote projects, trusted worktrees are persisted between Zed restarts. There's a way to clear all persisted trust with `workspace::ClearTrustedWorktrees`, this will restart Zed. This mechanism can be turned off with settings: ```jsonc "session": { "trust_all_worktrees": true } ``` in this mode, all worktrees will be trusted by default, allowing all actions, but no auto trust will be persisted: hence, when the setting is changed back, auto trusted worktrees will require another trust confirmation. This settings switch was added to the onboarding view also. Release Notes: - Introduced worktree trust mechanism, can be turned off with `"session": { "trust_all_worktrees": true }` --------- Co-authored-by: Matt Miller <mattrx@gmail.com> Co-authored-by: Danilo Leal <daniloleal09@gmail.com> Co-authored-by: John D. Swanson <swanson.john.d@gmail.com>
This commit is contained in:
1 parent
560d2c7c87
commit
b5ecc434d4
47 files changed
+4415
-178
No files matched your search
@@ -9,6 +9,8 @@ use serde::Deserialize;
|
||||
use smol::io::BufReader;
|
||||
use smol::{fs, lock::Mutex};
|
||||
use std::fmt::Display;
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::{
|
||||
env::{self, consts},
|
||||
ffi::OsString,
|
||||
@@ -46,6 +48,7 @@ struct NodeRuntimeState {
|
||||
last_options: Option<NodeBinaryOptions>,
|
||||
options: watch::Receiver<Option<NodeBinaryOptions>>,
|
||||
shell_env_loaded: Shared<oneshot::Receiver<()>>,
|
||||
trust_task: Option<Pin<Box<dyn Future<Output = ()> + Send>>>,
|
||||
}
|
||||
|
||||
impl NodeRuntime {
|
||||
@@ -53,9 +56,11 @@ impl NodeRuntime {
|
||||
http: Arc<dyn HttpClient>,
|
||||
shell_env_loaded: Option<oneshot::Receiver<()>>,
|
||||
options: watch::Receiver<Option<NodeBinaryOptions>>,
|
||||
trust_task: Option<Pin<Box<dyn Future<Output = ()> + Send>>>,
|
||||
) -> Self {
|
||||
NodeRuntime(Arc::new(Mutex::new(NodeRuntimeState {
|
||||
http,
|
||||
trust_task,
|
||||
instance: None,
|
||||
last_options: None,
|
||||
options,
|
||||
@@ -70,11 +75,15 @@ impl NodeRuntime {
|
||||
last_options: None,
|
||||
options: watch::channel(Some(NodeBinaryOptions::default())).1,
|
||||
shell_env_loaded: oneshot::channel().1.shared(),
|
||||
trust_task: None,
|
||||
})))
|
||||
}
|
||||
|
||||
async fn instance(&self) -> Box<dyn NodeRuntimeTrait> {
|
||||
let mut state = self.0.lock().await;
|
||||
if let Some(trust_task) = state.trust_task.take() {
|
||||
trust_task.await;
|
||||
}
|
||||
|
||||
let options = loop {
|
||||
if let Some(options) = state.options.borrow().as_ref() {
|
||||
|
||||
Reference in new issue
Block a user