fix: explicitly pass SSH identity file for DigitalOcean connections (#1784)

DigitalOcean SSH was failing with "Permission denied (publickey)" because
the SSH client was not explicitly told which identity file to use. When
users have multiple SSH keys or an SSH agent with different keys loaded,
SSH may try the wrong key first and fail — especially with BatchMode=yes
which suppresses interactive fallbacks.

The fix adds `-i ~/.ssh/id_ed25519` to SSH_OPTS (matching AWS's approach)
and passes sshKeyPath to the shared waitForSsh utility, ensuring the
correct key is always used for both the handshake wait and all subsequent
SSH/SCP commands.

Fixes #1783

Agent: code-health

Co-authored-by: B <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
A 2026-02-22 21:11:59 -08:00 committed by GitHub
parent 3988ffe90e
commit fa34d29b7e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 4 additions and 2 deletions

View file

@ -841,7 +841,8 @@ async function waitForDropletActive(dropletId: string, maxAttempts = 60): Promis
// ─── SSH Execution ───────────────────────────────────────────────────────────
const SSH_OPTS = SSH_BASE_OPTS;
const SSH_KEY_PATH = `${process.env.HOME}/.ssh/id_ed25519`;
const SSH_OPTS = [...SSH_BASE_OPTS, "-i", SSH_KEY_PATH];
export async function waitForCloudInit(ip?: string, _maxAttempts = 60): Promise<void> {
const serverIp = ip || doServerIp;
@ -849,6 +850,7 @@ export async function waitForCloudInit(ip?: string, _maxAttempts = 60): Promise<
host: serverIp,
user: "root",
maxAttempts: 36,
sshKeyPath: SSH_KEY_PATH,
});
// Stream cloud-init output so the user sees progress in real time