← All posts

Connecting to SFTP with an SSH key on a Mac

To use an SSH key for SFTP on a Mac, you create a key pair with ssh-keygen, add the public half to ~/.ssh/authorized_keys on the server, and connect with sftp -i pointing at the private half. That takes about five minutes. The part people trip over comes later: graphical Mac apps do not all reach your keys the same way, and sandboxed ones cannot read ~/.ssh or talk to ssh-agent at all.

Here is the whole process, including what to check when the server refuses your key.

Step 1: create a key pair on your Mac

Open Terminal and run:

ssh-keygen -t ed25519 -C "you@your-mac"

Accept the default location and set a passphrase when asked. You get two files:

Ed25519 keys are short, fast and supported by every OpenSSH release from 6.5 onwards. If you must reach a very old server that does not accept them, generate an RSA key instead with ssh-keygen -t rsa -b 4096. The passphrase encrypts the private key on disk, so a copied file is useless without it. The ssh-keygen manual covers the other options.

Step 2: install the public key on the server

If you can already log in with a password and have a shell, ssh-copy-id (included with recent macOS releases) does it in one go:

ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@example.com

Without it, this does the same thing by hand:

cat ~/.ssh/id_ed25519.pub | ssh deploy@example.com \
  'mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys'

SFTP-only accounts

Accounts restricted to SFTP have no shell, so neither command works. If the account can write to its own home folder, you can upload the key over SFTP itself:

sftp deploy@example.com
sftp> mkdir .ssh
sftp> chmod 700 .ssh
sftp> put /Users/you/.ssh/id_ed25519.pub .ssh/authorized_keys
sftp> chmod 600 .ssh/authorized_keys

Be careful: put replaces any existing authorized_keys file, removing other people's keys. Download it first and append if it already exists. On chrooted servers the administrator often keeps keys outside the chroot (set by AuthorizedKeysFile in sshd_config), in which case you send them the public key and they install it.

Step 3: connect with the key from Terminal

sftp -i ~/.ssh/id_ed25519 deploy@example.com

To avoid typing that every time, add a host entry to ~/.ssh/config:

Host example
    HostName example.com
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    AddKeysToAgent yes
    UseKeychain yes

Now sftp example is enough. UseKeychain is an Apple addition to OpenSSH that stores the key's passphrase in your login Keychain. You can also load it once with ssh-add --apple-use-keychain ~/.ssh/id_ed25519. Options are documented in ssh_config.

When the server refuses your SSH key

Run the connection with verbose output and read the lines about authentication:

sftp -v -i ~/.ssh/id_ed25519 deploy@example.com

Look for Offering public key followed by either Server accepts key or a fall-through to the next method. The usual causes, in rough order of frequency:

  1. Permissions. With its default StrictModes yes, sshd ignores authorized_keys if the file, ~/.ssh or the home folder is writable by group or others. Use 700 for ~/.ssh and 600 for the file.
  2. Wrong account. The key was added for ubuntu but you are logging in as deploy.
  3. A broken line. The public key must sit on a single line. Pasting through some editors wraps it.
  4. Key type not allowed. Newer OpenSSH servers reject RSA signatures using SHA-1, and some hardened configurations accept only certain key types.

The server's own log says exactly why it refused: /var/log/auth.log on Debian and Ubuntu, /var/log/secure on Red Hat family systems, or journalctl -u ssh (sshd on some distributions).

How Mac SFTP apps get at your SSH key

Command-line tools read ~/.ssh directly and can ask a running ssh-agent to sign on their behalf, through the socket named in SSH_AUTH_SOCK. Graphical apps vary. An app in Apple's App Sandbox, which every Mac App Store app is, can only open files you have picked for it. It cannot quietly reopen ~/.ssh/id_ed25519 on its next launch, and it cannot reach the agent's socket. So sandboxed apps ask you to choose the key once and keep their own secure copy.

That is not a weaker arrangement. A copy in the macOS Keychain is encrypted at rest and tied to the app, which is arguably better than a file in your home folder that any process you run can read.

Using an SSH key in Wharf

Wharf works the same way in both editions, whether from the website or the Mac App Store: it does not use ssh-agent and does not read ~/.ssh on its own. You import the key once:

  1. Add a site (or edit one) and set Protocol to SFTP.
  2. Under Authentication, set Method to SSH key, or SSH key + 2FA if the server also asks for a one-time code.
  3. Click Import Key…. The file picker opens at your ~/.ssh folder with hidden files shown. Choose the private key, not the .pub file.
  4. Enter the key's passphrase in Key passphrase if it has one, then click Save.

Wharf copies the private key into your Keychain, along with the matching .pub file if it sits next to it, and stores the passphrase there too. Nothing secret goes into its settings file, and deleting the site removes them. If you later replace the key on disk, import it again: Wharf uses its stored copy, not the file. The support page covers this under ssh-agent and ~/.ssh.

If the server turns the key down, Wharf reports that the private key was rejected and suggests checking the passphrase and that the key is in authorized_keys, which are the first two things to check from the list above.

On your first connection you will be asked to trust the server's host key. That is expected; here is how to check the fingerprint before clicking Trust. Wharf's privacy section explains how it handles credentials generally.