Skip to content

fix(devtools-proxy-support): support SSH password auth via keyboard-interactive COMPASS-10929 - #851

Open
TemaSM wants to merge 1 commit into
mongodb-js:mainfrom
TemaSM:fix/ssh-keyboard-interactive-password
Open

fix(devtools-proxy-support): support SSH password auth via keyboard-interactive COMPASS-10929#851
TemaSM wants to merge 1 commit into
mongodb-js:mainfrom
TemaSM:fix/ssh-keyboard-interactive-password

Conversation

@TemaSM

@TemaSM TemaSM commented Aug 3, 2026

Copy link
Copy Markdown

Fixes #839

Description

MongoDB Compass's SSH Password mode passes the configured password to ssh2, but does not opt in to keyboard-interactive authentication.
This makes SSH tunnels fail when an OpenSSH/PAM server accepts that password only through keyboard-interactive.

The SSH agent now enables tryKeyboard when a password is configured and uses it for one hidden, single-prompt challenge.
Empty rounds do not consume the attempt, while visible prompts, multiple prompts, and later rounds receive empty responses so the stored password is not reused for OTP or MFA prompts.

A per-connection authentication selector preserves the existing none → password → publickey → keyboard-interactive order.
Once the server reports partialSuccess, the keyboard-interactive password fallback is skipped for that connection, while other configured methods such as publickey remain available.
A reconnect starts with fresh authentication state.

This does not change the public API, connection options, or dependencies.

Root cause

SSHAgent passed password to ssh2.Client.connect(), but did not enable tryKeyboard or register the keyboard-interactive event handler required by ssh2.
Servers advertising publickey,keyboard-interactive therefore exhausted the configured authentication methods before Compass attempted to connect to MongoDB, showing user popup with text: All configured authentication methods failed.

The initial password fallback also needed to account for partialSuccess.
The default ssh2 method selector does not use that flag, so a server could accept password or publickey as one factor and then receive the configured password in its first hidden OTP prompt.

Changes

  • Enable tryKeyboard only when the SSH URL contains a password.
  • Answer only the first non-empty keyboard-interactive round containing exactly one hidden prompt.
  • Return empty responses for visible prompts, multiple prompts, and later non-empty rounds.
  • Keep the prompt state scoped to one SSH connection and reset it when a reusable client socket closes.
  • Use an internal per-connection authentication selector that keeps the supported order none → password → publickey → keyboard-interactive.
  • Track partialSuccess cumulatively and skip the keyboard-interactive password fallback after any method succeeds partially.
  • Keep other configured methods, including publickey, available after a partial success.
  • Accept methodsLeft without using it to reorder methods in this change.
  • Extend the local ssh2.Server fixture and add unit and integration coverage for password, public-key, partial-success, prompt-shape, rejection, and reconnection paths.

Security boundary

This is a password compatibility fallback, not a general interactive or MFA implementation.
Before any authentication method succeeds, the configured password is eligible only for the first non-empty round containing one hidden prompt.

After ssh2 reports partialSuccess, keyboard-interactive is skipped for the rest of that SSH connection.
A later failed method cannot clear that state, while a new connection receives a fresh selector.

Testing & validation

  • Added unit tests for authentication method selection and partialSuccess handling.
  • Extended the local ssh2.Server fixture to cover password, public-key, keyboard-interactive, and multi-step authentication.
  • Covered empty, visible, multiple, repeated, rejected, and reconnecting keyboard-interactive scenarios.
  • Targeted tests: 38 passing.
  • Full package suite: 85 passing, 3 pending.
  • TypeScript compilation and package checks pass.

Tested with Node.js 22.23.1 and npm 11.17.0:

  • npm run test --workspace=@mongodb-js/devtools-proxy-support -- src/ssh-auth.spec.ts src/ssh.spec.ts: 38 passing
  • npm run compile --workspace=@mongodb-js/devtools-proxy-support: passing
  • npm run check --workspace=@mongodb-js/devtools-proxy-support: passing
  • npm run test-ci --workspace=@mongodb-js/devtools-proxy-support: 85 passing, 3 pending, 0 failing

The basic keyboard-interactive password path was also tested manually with a locally patched Compass 1.49.12 build against a server advertising publickey,keyboard-interactive.
The partialSuccess boundary is covered by the automated SSH server fixture.

Open Questions

None.

Checklist

@Anemy Anemy changed the title fix(devtools-proxy-support): support SSH password auth via keyboard-interactive fix(devtools-proxy-support): support SSH password auth via keyboard-interactive COMPASS-10929 Aug 3, 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.

SSH proxy (tunnel) password authentication fails with keyboard-interactive-only servers

1 participant