agents: add keyboard-interactive SSH auth fallback#315590
Merged
Merged
Conversation
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>
Contributor
There was a problem hiding this comment.
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-interactiveas 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
IQuickInputServiceand forward responses back to the shared process. - Update/add unit tests to reflect the extra auth attempt and validate
makeAuthHandlerkeyboard-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
Contributor
|
Base:
|
- 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>
…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>
bhavyaus
approved these changes
May 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:Change
Adds a
keyboard-interactiveattempt as the final fallback in Agent mode. When ssh2 picks it:onDidRequestKeyboardInteractivewith the server-supplied promptsSSHRemoteAgentHostService) bridges toIQuickInputService— one input per prompt, masked whenecho: falserespondKeyboardInteractivePassword and KeyFile modes are unchanged.
Files
common/sshRemoteAgentHost.ts— newISSHKeyboardInteractivePrompt/ISSHKeyboardInteractiveRequesttypes and main-service event/method surfacenode/sshRemoteAgentHostService.ts— newkeyboard-interactivevariant inSSHAuthAttempt,makeAuthHandleraccepts an optionalkbiHandler, Agent mode appends the kbi fallback, per-connection emitters + cancellationelectron-browser/sshRemoteAgentHostServiceImpl.ts— injectsIQuickInputService, subscribes to the request event, prompts user, responds (or cancels)testBuildAuthAttemptsupdated to expect the trailing kbi entry; newmakeAuthHandlertest verifies kbi routing + skip-when-no-handler; renderer test mock has stubs for the new event/methodValidation
npm run compile-check-ts-native✅npm run hygiene✅(Written by Copilot)