Skip to content

agents: add keyboard-interactive SSH auth fallback#315590

Merged
roblourens merged 4 commits into
mainfrom
roblou/agents/ssh-authentication-issue-fix
May 11, 2026
Merged

agents: add keyboard-interactive SSH auth fallback#315590
roblourens merged 4 commits into
mainfrom
roblou/agents/ssh-authentication-issue-fix

Conversation

@roblourens
Copy link
Copy Markdown
Member

@roblourens roblourens commented May 11, 2026

Fixes #315588

Problem

When connecting to a configured SSH host in Agent mode, the connection only attempted SSH agent + default identity files. For hosts that require password / 2FA via keyboard-interactive auth (which works fine via the OpenSSH CLI), all attempts failed with All configured authentication methods failed:

[SSHRemoteAgentHost] Built 2 auth attempt(s): agent, publickey ~/.ssh/id_rsa
[SSHRemoteAgentHost] Trying auth: agent
[SSHRemoteAgentHost] Trying auth: publickey ~/.ssh/id_rsa
[SSHRemoteAgentHost] No more auth methods to try; giving up
[SSHRemoteAgentHost] SSH connection error: All configured authentication methods failed

Change

Adds a keyboard-interactive attempt as the final fallback in Agent mode. When ssh2 picks it:

  1. Main process emits onDidRequestKeyboardInteractive with the server-supplied prompts
  2. Renderer (SSHRemoteAgentHostService) bridges to IQuickInputService — one input per prompt, masked when echo: false
  3. Responses are forwarded back via respondKeyboardInteractive
  4. User cancellation, or connect ready/error from ssh2, results in empty responses being submitted so the auth attempt fails cleanly instead of hanging

Password and KeyFile modes are unchanged.

Files

  • common/sshRemoteAgentHost.ts — new ISSHKeyboardInteractivePrompt / ISSHKeyboardInteractiveRequest types and main-service event/method surface
  • node/sshRemoteAgentHostService.ts — new keyboard-interactive variant in SSHAuthAttempt, makeAuthHandler accepts an optional kbiHandler, Agent mode appends the kbi fallback, per-connection emitters + cancellation
  • electron-browser/sshRemoteAgentHostServiceImpl.ts — injects IQuickInputService, subscribes to the request event, prompts user, responds (or cancels)
  • Tests for testBuildAuthAttempts updated to expect the trailing kbi entry; new makeAuthHandler test verifies kbi routing + skip-when-no-handler; renderer test mock has stubs for the new event/method

Validation

  • npm run compile-check-ts-native
  • npm run hygiene
  • Manual SSH test against a password-only host pending

(Written by Copilot)

When connecting to a configured SSH host in Agent mode, ssh2 only
attempted SSH agent + default identity files. For hosts that require
password / 2FA via keyboard-interactive (working fine via the OpenSSH
CLI), all attempts failed with 'All configured authentication methods
failed'.

This appends a 'keyboard-interactive' attempt as the final fallback in
Agent mode. When ssh2 picks it, the main process emits a request event
that the renderer bridges to  one prompt per serverIQuickInputService
challenge, masked when echo is false. Cancellation (user dismissal or
underlying connect failure) sends empty responses so ssh2 surfaces a
proper auth failure instead of hanging.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 11, 2026 01:57
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a keyboard-interactive authentication fallback to the SSH “Agent” auth mode used by the Agent Host, enabling password / 2FA flows when SSH agent + key-based auth fails (matching typical OpenSSH CLI behavior). It extends the shared-process SSH service to surface keyboard-interactive prompts to the renderer, where the user is prompted via Quick Input and responses are sent back to complete the auth attempt.

Changes:

  • Add keyboard-interactive as a final auth attempt in Agent mode and route ssh2 prompt callbacks to the renderer via new IPC events/methods.
  • Implement renderer-side prompt collection using IQuickInputService and forward responses back to the shared process.
  • Update/add unit tests to reflect the extra auth attempt and validate makeAuthHandler keyboard-interactive behavior.
Show a summary per file
File Description
src/vs/platform/agentHost/common/sshRemoteAgentHost.ts Adds keyboard-interactive request/prompt types and new main-service event/method surface for KBI prompts.
src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts Adds keyboard-interactive auth attempt + handler plumbing, emits KBI prompt requests, tracks pending requests, and accepts responses.
src/vs/platform/agentHost/electron-browser/sshRemoteAgentHostServiceImpl.ts Bridges KBI prompt requests to Quick Input prompts and responds back to the main service.
src/vs/platform/agentHost/test/node/sshRemoteAgentHostService.test.ts Updates auth-attempt ordering expectations and adds makeAuthHandler keyboard-interactive tests.
src/vs/platform/agentHost/test/electron-browser/sshRemoteAgentHostService.test.ts Updates renderer test stubs to include the new KBI event/method surface.

Copilot's findings

  • Files reviewed: 5/5 changed files
  • Comments generated: 2

Comment thread src/vs/platform/agentHost/node/sshRemoteAgentHostService.ts
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 11, 2026

Base: 0f347dc4 Current: 6e161a7b

No screenshot changes.

- Main side: cancelLiveKbiRequests now also invokes ssh2's stored
  finish callback with an empty array, so ssh2 stops waiting on this
  attempt instead of hanging until readyTimeout when a connect attempt
  is aborted mid-prompt.
- Renderer side: pass a CancellationToken into IQuickInputService.input
  so an in-flight prompt is dismissed immediately when the main side
  cancels, instead of relying on the user to interact with stale UI.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
roblourens and others added 2 commits May 11, 2026 10:08
…uthHandler

Extracts two pure helpers so the iteration loop reads top-to-bottom
without nested if/else branches around callback construction:

- isMethodAllowedByServer encapsulates the agent->publickey aliasing
- toAuthMethod maps SSHAuthAttempt to ssh2's payload, including the
  unavoidable kbi prompt-bridge closure (now isolated, not tangled
  with iteration state)

No behavior change.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@roblourens roblourens marked this pull request as ready for review May 11, 2026 18:40
@roblourens roblourens enabled auto-merge (squash) May 11, 2026 18:40
@roblourens roblourens merged commit cb383df into main May 11, 2026
25 checks passed
@roblourens roblourens deleted the roblou/agents/ssh-authentication-issue-fix branch May 11, 2026 18:41
@vs-code-engineering vs-code-engineering Bot added this to the 1.121.0 milestone May 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

AgentHost: keyboard-interactive auth not implemented

3 participants