Category: Access and AuthenticationUpdated 2026-10-18

ssh-copy-id

ssh-copy-id is a script that ships with OpenSSH and installs your public key on a remote server. It logs in over SSH, usually with a password, skips keys that are already installed and appends the rest to the account's ~/.ssh/authorized_keys, creating the directory and file when needed. It is the usual first step before password login is turned off.

What ssh-copy-id does, step by step

According to the ssh-copy-id manual, the script uses ssh to log in to the remote machine, "presumably using a login password", so password authentication has to be enabled for the first run. It builds a list of keys, tries to log in with each one to see whether it is already installed, and then installs only those that failed. By default it appends them to ~/.ssh/authorized_keys, creating the file and directory if necessary.

Reading the script itself shows the details. On the remote side it sets umask 077, so a new directory is private and a new file is readable only by its owner. It adds a missing trailing newline before appending, so keys do not run together, and it runs restorecon when that command exists, which restores SELinux labels. It never removes existing keys.

Which keys it copies depends on the options. With -i it uses only that file. Without it, if ssh-add -L prints anything, the keys in your agent are used, and otherwise the most recently changed ~/.ssh/id*.pub file.

Commands and a manual alternative

Use a Host alias from ~/.ssh/config so you do not retype the server details. First do a dry run, which only prints the keys that would be installed, then install for real:

ssh-copy-id -n -i ~/.ssh/id_ed25519.pub myserver
ssh-copy-id -i ~/.ssh/id_ed25519.pub myserver
ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 2222 myserver

The manual lists -p for the port, -o and -F to pass ssh options or a config file, -t for another target file, -f to skip the "already installed" check, and -s to use sftp when the server restricts remote commands. Check the result with a key-only login:

ssh -o IdentitiesOnly=yes -o PasswordAuthentication=no -i ~/.ssh/id_ed25519 myserver

If the script is not available, the same thing by hand is:

cat ~/.ssh/id_ed25519.pub | ssh myserver 'umask 077; mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys'

The manual method does not check for duplicates or a missing final newline, so look at the file afterwards.

Gotchas and mistakes

Several defaults surprise people.

Install keys for a named admin account rather than root (see PermitRootLogin).

A safe workflow before disabling password login

Copying the key is step one of moving to key-based authentication, and the order matters.

  1. Create a key with ssh-keygen, using a passphrase.
  2. Install it with ssh-copy-id -i, keeping your original session open.
  3. From a second terminal, log in with the key only and confirm it works.
  4. Edit the server configuration, then run sudo sshd -t and reload.
  5. From a third terminal, confirm that the key still works and that a password-only attempt is refused.

The SSH hardening guide gives the exact PasswordAuthentication and related lines. If it goes wrong, the locked-out recovery guide shows how to get back in through the provider console.

Treat the install as an access change: record whose key it is, and when someone leaves, delete their line. For a hardware-backed key, see FIDO2 and WebAuthn and the SSH two-factor authentication guide.

Related terms: authorized_keys, Key-based authentication, ssh-keygen, PasswordAuthentication, PermitRootLogin.

Frequently asked questions

What does ssh-copy-id do?

It logs in to the server over SSH and appends your public key to ~/.ssh/authorized_keys, creating the directory and file if needed. It first checks which of your keys are already installed and skips them.

Do I need password login enabled to use ssh-copy-id?

Normally yes for the first run, since the script logs in with a password to install the key. If password login is already off, add the key through another working login or your provider console.

How do I copy a specific key with ssh-copy-id?

Use the -i option with the public key file, for example ssh-copy-id -i ~/.ssh/id_ed25519.pub myserver. Without -i the script uses the keys in your ssh-agent, or otherwise the most recent id*.pub file.

What if ssh-copy-id is not installed?

Append the key by hand: pipe the .pub file to ssh and run mkdir -p ~/.ssh and cat >> ~/.ssh/authorized_keys on the server with umask 077. Then check that the directory is 700 and the file 600.

Does ssh-copy-id remove old keys?

No. It only appends keys that are missing. Review authorized_keys yourself and delete lines for former staff or retired devices.

Want to see where your own server stands?

Run the free, read-only server check, or open the Security Lab and watch the detect, contain, recover, verify loop in action.

Get your free server checkOpen the Security Lab