From 573404199395d5ceaaa7dad08ae74da9017b8f43 Mon Sep 17 00:00:00 2001 From: Ehab Younes Date: Thu, 16 Jul 2026 13:34:39 +0000 Subject: [PATCH] fix: scope machine-only settings to application (#1032) Change coder.binarySource, coder.binaryDestination, coder.headerCommand, coder.tlsCertFile, coder.tlsKeyFile, coder.tlsCaFile, coder.tlsAltHost, coder.tlsCertRefreshCommand, coder.proxyLogDirectory, coder.proxyBypass, coder.sshConfig, coder.sshFlags, and coder.globalFlags from machine to application scope (all keep ignoreSync, so Settings Sync is unchanged). application scope keeps the SEC-200 goal of blocking workspace/folder overrides while fixing #1032: in a remote window VS Code filters machine-scoped keys out of the local User settings.json, so such a value holds only until the extension registers its schema on activation. The next re-parse of settings.json (edit, Settings Sync write, profile switch, or tasks.json load) then drops it to the default, with no remote-side fallback. application scope is honored regardless of timing. Document the mechanism and reproduction in the README and PR #1034. --- CHANGELOG.md | 8 ++++++++ README.md | 15 +++++++++++++++ package.json | 39 ++++++++++++++++++++++++++------------- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4aeba367c..b8fb9a657 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,14 @@ - Apply a 60-second default timeout to REST requests, so requests hung on a half-open TCP connection don't stall pollers forever. +- Change `coder.binarySource`, `coder.binaryDestination`, `coder.headerCommand`, + `coder.tlsCertFile`, `coder.tlsKeyFile`, `coder.tlsCaFile`, `coder.tlsAltHost`, + `coder.tlsCertRefreshCommand`, `coder.proxyLogDirectory`, `coder.proxyBypass`, + `coder.sshConfig`, `coder.sshFlags`, and `coder.globalFlags` from `machine` + to `application` scope (still `ignoreSync`, unchanged from before). This + keeps workspace/folder `settings.json` from overriding them (the original + SEC-200 goal) while fixing #1032, where a `machine`-scoped value could + revert to its default in a remote window. ## [v1.15.2](https://github.com/coder/vscode-coder/releases/tag/v1.15.2) 2026-06-30 diff --git a/README.md b/README.md index b193dc81d..4c981606d 100644 --- a/README.md +++ b/README.md @@ -51,6 +51,21 @@ Alternatively, manually install the VSIX from the All extension settings are under the `coder.*` namespace in the Settings UI. Paths in settings accept `~` and `${userHome}` from VS Code's [variables reference](https://code.visualstudio.com/docs/editor/variables-reference). +Several `coder.*` settings (paths, commands, hostnames, and proxy bypass +lists) are excluded from Settings Sync via `ignoreSync`, because their +values can depend on the specific machine or network where they were set. + +> [!WARNING] +> Do not give any `coder.*` setting `"scope": "machine"`. In a remote +> window VS Code filters `machine`-scoped keys out of the local User +> `settings.json`, so such a value only holds until the extension +> registers its schema on activation. After that, the next re-parse of +> `settings.json` (from an edit, a Settings Sync write, a profile switch, +> or a `tasks.json` load) drops the value back to its default, with no +> remote-side copy to fall back on. This intermittent revert is the cause +> of #1032. Use `application` scope instead: it is honored in remote +> windows regardless of timing. See #1034 for the mechanism and +> reproduction. ## URI Handler diff --git a/package.json b/package.json index a1ca7b3f9..34ce8f35c 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,8 @@ "type": "string", "pattern": "^[a-zA-Z0-9-]+[=\\s].*$" }, - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.insecure": { "markdownDescription": "If true, the extension will not verify the authenticity of the remote host. This is useful for self-signed certificates.", @@ -66,13 +67,15 @@ "markdownDescription": "Used to download the Coder CLI which is necessary to make SSH connections. The If-None-Match header will be set to the SHA1 of the CLI and can be used for caching. Absolute URLs will be used as-is; otherwise this value will be resolved against the deployment domain. Defaults to downloading from the Coder deployment.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.binaryDestination": { "markdownDescription": "The path to the Coder CLI binary or the directory containing it. When set to a file path (e.g., `/usr/bin/coder`), the extension checks its version and downloads a replacement if it does not match the server (and downloads are enabled). When set to a directory, the extension looks for the CLI inside it (downloading if enabled). Defaults to the value of `CODER_BINARY_DESTINATION` if not set, otherwise the extension's global storage directory.\n\nSupports `${env:VAR}`, `${userHome}`, and a leading `~`.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.enableDownloads": { "markdownDescription": "Allow the plugin to download the CLI when missing or out of date.", @@ -84,50 +87,58 @@ "markdownDescription": "An external command that outputs additional HTTP headers added to all requests. The command must output each header as `key=value` on its own line. The following environment variables will be available to the process: `CODER_URL`. Defaults to the value of `CODER_HEADER_COMMAND` if not set.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.tlsCertFile": { "markdownDescription": "Path to file for TLS client cert. When specified, token authorization will be skipped. `http.proxySupport` must be set to `on` or `off`, otherwise VS Code will override the proxy agent set by the plugin.\n\nSupports `${env:VAR}`, `${userHome}`, and a leading `~`.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.tlsKeyFile": { "markdownDescription": "Path to file for TLS client key. When specified, token authorization will be skipped. `http.proxySupport` must be set to `on` or `off`, otherwise VS Code will override the proxy agent set by the plugin.\n\nSupports `${env:VAR}`, `${userHome}`, and a leading `~`.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.tlsCaFile": { "markdownDescription": "Path to file for TLS certificate authority. `http.proxySupport` must be set to `on` or `off`, otherwise VS Code will override the proxy agent set by the plugin.\n\nSupports `${env:VAR}`, `${userHome}`, and a leading `~`.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.tlsAltHost": { "markdownDescription": "Alternative hostname to use for TLS verification. This is useful when the hostname in the certificate does not match the hostname used to connect.\n\nSupports `${env:VAR}` substitution.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.tlsCertRefreshCommand": { "markdownDescription": "Command to run when TLS client certificate errors occur (e.g., expired, revoked, or rejected certificates). If configured, the extension will automatically execute this command and retry failed requests. `http.proxySupport` must be set to `on` or `off`, otherwise VS Code will override the proxy agent set by the plugin.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.proxyLogDirectory": { "markdownDescription": "Directory where the Coder CLI outputs SSH connection logs for debugging. Defaults to the value of `CODER_SSH_LOG_DIR` if not set, otherwise the extension's global storage directory.\n\nSupports `${env:VAR}`, `${userHome}`, and a leading `~`.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.proxyBypass": { "markdownDescription": "If not set, will inherit from the `no_proxy` or `NO_PROXY` environment variables. Has no effect when `http.proxySupport` is set to `off`. With values other than `on`, VS Code will override the proxy agent set by the plugin.", "markdownDeprecationMessage": "Deprecated: prefer `http.noProxy`.", "type": "string", "default": "", - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.defaultUrl": { "markdownDescription": "This will be shown in the URL prompt, along with the CODER_URL environment variable if set, for the user to select when logging in.", @@ -180,7 +191,8 @@ "default": [ "--disable-autostart" ], - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.globalFlags": { "markdownDescription": "Global flags to pass to every Coder CLI invocation. Enter each flag as a separate array item, in order. Do **not** include the `coder` command itself. See the [CLI reference](https://coder.com/docs/reference/cli) for available global flags.\n\nSupports `${env:VAR}`, `${userHome}`, and a leading `~`. For `--flag=value` items the expansion applies to the value half, so `--cfg=~/coder` works.\n\nSet `--global-config` here to point the CLI at a shared config directory (e.g. `--global-config=~/.config/coderv2` to share login/auth with the Coder CLI); requires a deployment on 2.31.0+ and is ignored when `#coder.useKeyring#` is active. The `--use-keyring` flag is ignored; use `#coder.useKeyring#` instead.\n\nFor `--header-command`, precedence is: `#coder.headerCommand#` setting, then `CODER_HEADER_COMMAND` environment variable, then the value specified here.", @@ -188,7 +200,8 @@ "items": { "type": "string" }, - "scope": "machine" + "scope": "application", + "ignoreSync": true }, "coder.useKeyring": { "markdownDescription": "Store session tokens in the OS keyring (macOS Keychain, Windows Credential Manager) instead of plaintext files. Requires CLI >= 2.29.0 (>= 2.31.0 to sync login from CLI to VS Code). This will attempt to sync between the CLI and VS Code since they share the same keyring entry. It will log you out of the CLI if you log out of the IDE, and vice versa. Has no effect on Linux.",