diff --git a/Cargo.lock b/Cargo.lock index 96c50f7e5f..ff59094127 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -16697,7 +16697,6 @@ dependencies = [ "command_palette_hooks", "component_preview", "copilot", - "credentials_provider", "db", "diagnostics", "editor", diff --git a/crates/credentials_provider/src/credentials_provider.rs b/crates/credentials_provider/src/credentials_provider.rs index 86561b2d04..f72fd6c39b 100644 --- a/crates/credentials_provider/src/credentials_provider.rs +++ b/crates/credentials_provider/src/credentials_provider.rs @@ -9,13 +9,17 @@ use futures::FutureExt as _; use gpui::{App, AsyncApp}; use release_channel::ReleaseChannel; -/// An environment variable whose presence indicates that the development auth -/// provider should be used. +/// An environment variable whose presence indicates that the system keychain +/// should be used in development. /// -/// Only works in development. Setting this environment variable in other release -/// channels is a no-op. -pub static ZED_DEVELOPMENT_AUTH: LazyLock = LazyLock::new(|| { - std::env::var("ZED_DEVELOPMENT_AUTH").map_or(false, |value| !value.is_empty()) +/// By default, running Zed in development uses the development credentials +/// provider. Setting this environment variable allows you to interact with the +/// system keychain (for instance, if you need to test something). +/// +/// Only works in development. Setting this environment variable in other +/// release channels is a no-op. +static ZED_DEVELOPMENT_USE_KEYCHAIN: LazyLock = LazyLock::new(|| { + std::env::var("ZED_DEVELOPMENT_USE_KEYCHAIN").map_or(false, |value| !value.is_empty()) }); /// A provider for credentials. @@ -57,13 +61,21 @@ impl dyn CredentialsProvider { } fn new(cx: &App) -> Arc { - let use_development_backend = match ReleaseChannel::try_global(cx) { - Some(ReleaseChannel::Dev) => *ZED_DEVELOPMENT_AUTH, + let use_development_provider = match ReleaseChannel::try_global(cx) { + Some(ReleaseChannel::Dev) => { + // In development we default to using the development + // credentials provider to avoid getting spammed by relentless + // keychain access prompts. + // + // However, if the `ZED_DEVELOPMENT_USE_KEYCHAIN` environment + // variable is set, we will use the actual keychain. + !*ZED_DEVELOPMENT_USE_KEYCHAIN + } Some(ReleaseChannel::Nightly | ReleaseChannel::Preview | ReleaseChannel::Stable) | None => false, }; - if use_development_backend { + if use_development_provider { Arc::new(DevelopmentCredentialsProvider::new()) } else { Arc::new(KeychainCredentialsProvider) diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index f9f13e4de1..529c5f8b6b 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -41,7 +41,6 @@ command_palette.workspace = true command_palette_hooks.workspace = true component_preview.workspace = true copilot.workspace = true -credentials_provider.workspace = true db.workspace = true diagnostics.workspace = true editor.workspace = true diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 8ab32e9da7..6ec65acb40 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -723,10 +723,10 @@ fn handle_open_request(request: OpenRequest, app_state: Arc, cx: &mut async fn authenticate(client: Arc, cx: &AsyncApp) -> Result<()> { if stdout_is_a_pty() { - if *credentials_provider::ZED_DEVELOPMENT_AUTH { - client.authenticate_and_connect(true, cx).await?; - } else if client::IMPERSONATE_LOGIN.is_some() { + if client::IMPERSONATE_LOGIN.is_some() { client.authenticate_and_connect(false, cx).await?; + } else { + client.authenticate_and_connect(true, cx).await? } } else if client.has_credentials(cx).await { client.authenticate_and_connect(true, cx).await?; diff --git a/docs/src/development.md b/docs/src/development.md index 0f24ac3c59..980b47aa4d 100644 --- a/docs/src/development.md +++ b/docs/src/development.md @@ -10,30 +10,33 @@ If you'd like to develop collaboration features, additionally see: - [Local Collaboration](./development/local-collaboration.md) -## Authentication +## Keychain access -When developing Zed you will typically want to sign in to the production collab -instance, unless you are specifically working on features that require running -collab locally. +Zed stores secrets in the system keychain. -In order to bypass the keychain prompts that pop up when trying to sign in each -time you run a development build of Zed, you can use the development auth -provider. +However, when running a development build of Zed on macOS (and perhaps other +platforms) trying to access the keychain results in a lot of keychain prompts +that require entering your password over and over. -This will store your Zed access token in a local file on disk that can be read -in development, bypassing the need to retrieve the credential from the system -keychain. +On macOS this is caused by the development build not having a stable identity. +Even if you choose the "Always Allow" option, the OS will still prompt you for +your password again the next time something changes in the binary. -To enable the development auth provider, set this in your shell: +This quickly becomes annoying and impedes development speed. + +That is why, by default, when running a development build of Zed an alternative +credential provider is used in order to bypass the system keychain. + +> Note: This is **only** the case for development builds. For all non-development +> release channels the system keychain is always used. + +If you need to test something out using the real system keychain in a +development build, run Zed with the following environment variable set: ``` -ZED_DEVELOPMENT_AUTH=1 +ZED_DEVELOPMENT_USE_KEYCHAIN=1 ``` -You may want to add this to your shell profile so you don't need to remember to enable it each time. - -> Note: This only works for development builds. It is a no-op in all non-development release channels. - ## Contributor links - [CONTRIBUTING.md](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md)