Skip to content

SSH key path is hardcoded, ignores non-default key locations #11

@gabiudrescu

Description

@gabiudrescu

Bug

SSHConnect() in internal/hetzner/client.go (line 282) hardcodes the SSH private key lookup to ~/.ssh/id_ed25519 and ~/.ssh/id_rsa. If the user's SSH key has a different filename (e.g. ~/.ssh/my_project_key), Specter cannot connect even though the correct public key is uploaded to Hetzner and configured via ssh_key_name.

Steps to Reproduce

  1. Generate an SSH key with a custom name: ssh-keygen -t ed25519 -f ~/.ssh/my_project_key
  2. Upload it to Hetzner: hcloud ssh-key create --name my-key --public-key-from-file ~/.ssh/my_project_key.pub
  3. Run specter init — picks up my-key correctly
  4. Run specter image build
  5. VM is created, boots, but SSH connection hangs indefinitely (retrying every 3s with the wrong key)

Expected Behavior

Specter should resolve the local private key path from the configured ssh_key_name, or allow the user to specify the private key path in the config. SSH agent forwarding (SSH_AUTH_SOCK) could also be checked as a fallback.

Actual Behavior

SSHConnect() only tries ~/.ssh/id_ed25519 then ~/.ssh/id_rsa. If neither matches the key uploaded to Hetzner, the connection fails silently in a retry loop with no error message to the user.

Relevant Code

// internal/hetzner/client.go:282-313
func SSHConnect(ip string) (*ssh.Client, error) {
    home, _ := os.UserHomeDir()
    keyBytes, err := os.ReadFile(filepath.Join(home, ".ssh", "id_ed25519"))
    if err != nil {
        keyBytes, err = os.ReadFile(filepath.Join(home, ".ssh", "id_rsa"))
        // ...
    }
}

Proposed Fix

I'd like to contribute a fix. The approach would be:

  1. Add an optional ssh_key_path field to the config (~/.specter/config.yaml)
  2. If set, use that path directly
  3. If not set, try the SSH agent (SSH_AUTH_SOCK) first, then fall back to the current id_ed25519 / id_rsa defaults
  4. Surface a clear error message if no usable key is found, instead of silently retrying

Workaround

Symlink your key to the default path:

mv ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.backup
ln -s ~/.ssh/my_project_key ~/.ssh/id_ed25519

Environment

  • Specter v0.1.0
  • macOS (darwin/arm64)
  • SSH key type: ed25519 with custom filename

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions