Repository navigation
fix(ssh): preserve configured aliases in host suggestions - #16723
georgenijo wants to merge 8 commits into
Conversation
| ? (rawArgs[1]?.split(",") ?? []) | ||
| : null; | ||
| } | ||
| if (normalizedDirective === "hostname" && context.patterns && context.patterns.length > 0) { |
There was a problem hiding this comment.
🟡 Medium src/config.ts:201
A HostName inside an unsupported Match condition such as Match exec is discarded, so a later Host block's HostName is reported as the target even when the match succeeds and SSH's first-obtained-value semantics select the earlier hostname; this can hide the actual host from known_hosts. Preserve an unresolved first-value rule for that conditional HostName so later values cannot falsely resolve the target, and retain the alias as a fallback.
🤖 Copy this AI Prompt to have your agent fix this:
In file @packages/ssh/src/config.ts around line 201:
A `HostName` inside an unsupported `Match` condition such as `Match exec` is discarded, so a later `Host` block's `HostName` is reported as the target even when the match succeeds and SSH's first-obtained-value semantics select the earlier hostname; this can hide the actual host from `known_hosts`. Preserve an unresolved first-value rule for that conditional `HostName` so later values cannot falsely resolve the target, and retain the alias as a fallback.
There was a problem hiding this comment.
Fixed in c0ca256. An unresolved conditional HostName now reserves the first value instead of allowing a later HostName to falsely resolve the alias. Discovery keeps the alias fallback and raw known_hosts candidates. Regression coverage includes direct Match exec, included guarded rules, an earlier unconditional value, and unrelated guarded hosts; the 26 focused SSH/discovery tests pass.
There was a problem hiding this comment.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
| condition === "all" && rawArgs.length === 1 | ||
| ? ["*"] | ||
| : condition === "originalhost" && rawArgs.length === 2 | ||
| ? (rawArgs[1]?.split(",") ?? []) |
There was a problem hiding this comment.
🟡 Medium src/config.ts:198
Match originalhost "work" does not match the alias work, so the following HostName work.example rule is ignored and discovery searches for work instead of work.example, retaining the duplicate known_hosts target. The argument is split without removing its quotes; unquote it before splitting the pattern list, as HostName values are.
| ? (rawArgs[1]?.split(",") ?? []) | |
| ? (rawArgs[1]?.replace(/^("|')(.*)\1$/u, "$2").split(",") ?? []) |
🤖 Copy this AI Prompt to have your agent fix this:
In file @packages/ssh/src/config.ts around line 198:
`Match originalhost "work"` does not match the alias `work`, so the following `HostName work.example` rule is ignored and discovery searches for `work` instead of `work.example`, retaining the duplicate `known_hosts` target. The argument is split without removing its quotes; unquote it before splitting the pattern list, as `HostName` values are.
There was a problem hiding this comment.
Fixed in c0ca256. Whole quoted Match originalhost arguments are unquoted before matching the comma-separated patterns. Regression fixtures cover double-quoted single names, single-quoted comma lists, nonmatches, and conservatively unresolved mixed quoting. All 26 focused SSH/discovery tests pass.
There was a problem hiding this comment.
Sorry, I'm unable to act on this request because you do not have permissions within this repository.
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — The change modifies production SSH discovery and suggestion behavior by adding nontrivial HostName, Include, and Match parsing plus target de-duplication. Unresolved Medium findings identify conditional configuration cases that can still produce incorrect host suggestions. Not approved because:
Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (2)
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughSSH host discovery now applies supported SSH config hostname rules and avoids listing known-host entries that match configured aliases or targets. Host search also matches configured hostnames case-insensitively. ChangesSSH host discovery
Priority: ➖ Normal Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Bug fix · Severity of issue fixed: Medium Suggested reviewers: Merge Risk: ⚪ Minimal · up to The SSH suggestion changes are mergeable. A raw hostname using a different port may not appear as a suggestion, but it can still be entered directly. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The changed suggestions preserve aliases when connecting, so configured SSH settings remain authoritative. No introduced security-boundary bypass was established. Risk is limited, but discovery only approximates dynamic SSH configuration and the security assessment is not exhaustive. Retained concerns Security review detailsSecurity Blast Radius
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
188d126 to
e9f7b77
Compare
|
@macroscope-app review Please review the current head c0ca256. Both findings from the earlier 7606475 review are fixed, with regression coverage and replies in the original threads. The 26 focused tests pass; the latest CodeRabbit review has no actionable findings. GitHub Actions remain awaiting maintainer approval to run. |
|
Sorry, I'm unable to act on this request because you do not have permissions within this repository. |
What Changed
SSH host discovery preserves configured aliases, hides their duplicate
known_hoststargets, and lets users search for an alias by its target address. Connections still use the alias and its SSH settings. Target resolution follows first-value precedence across Includes and matching Host/Match blocks; unsupported dynamic rules fall back conservatively.Why
With
Host build-box/HostName build-box.example.testand that address inknown_hosts, the picker currently suggests both entries. Choosing the raw target can bypass the configured user or routing settings. This is a focused fix for that existing picker behavior, not a new connection workflow.Fixes #13270. Replaces #13269, which was closed for missing before/after UI evidence. The requested evidence is included below from the original submitted revision. The original five source patches rebased unchanged onto upstream main
10f39eb9ac(git range-diffreports identical patches). A final review follow-up conservatively retains aliases under unevaluated Match conditions and bounds Include traversal to 16 levels / 256 file reads. Includes under a known non-matching Host block are excluded, as in SSH config semantics.Verification
On the replacement branch:
vp test run packages/ssh/src/config.test.ts apps/web/src/state/desktopSshHosts.test.ts apps/desktop/src/ssh/DesktopSshEnvironment.test.ts: 26 tests passed, covering target de-duplication, config precedence, conditional Includes, wildcard Host, Match rules, tokenized/quoted values, bridge behavior and hostname search.claude-opus-5-5, high effort) review and recheck passed on7606475b6a. Macroscope then identified two further first-value/quoted-Match cases;188d126d2ffixes both, with 25 focused tests passing. Independent Claude Opus 5.5 rechecks passed on the first-value fixes and on the finalc0ca2566e4conservative handling of complex quoted patterns; all 26 focused tests pass.Upstream CI and preview workflows are currently
action_required: GitHub requires maintainer approval for this fork contribution. Local verification does not replace that gate.UI Changes
Captured the running Electron 44.4.2 app, production preload/IPC and SSH discovery on the submitted head
0f6216edb3and its original basef5ef0ddb90, with isolated app state and an X11 display.Both capture builds temporarily pass the same explicit
homeDirto the discovery call. Its disposable fixture containsHost build-box,HostName build-box.example.test, and a matching raw hostname inknown_hosts. No real SSH configuration was read and no SSH connection was attempted. This test-only fixture injection is not part of the PR. Capture procedure and provenance.Settings → Connections → Add environment → SSH, empty focused host field:
Before: the alias and its raw target are separate suggestions.
After: the configured alias is preserved and the duplicate target is suppressed.
Searching by the target address
build-box.example.testfinds the configuredbuild-boxalias.Before hostname-search capture: it returns the raw target.
Checklist
Authored with GPT models through the Codex harness; replacement prepared with GPT-6.1 Sol and independently reviewed by Claude Opus 5.5 at high effort.