Generate the key on the machine you sit at
Not on the server. The private half should never exist on a host you might lose access to, and copying it around defeats the point of having one.
ssh-keygen -t ed25519 -a 100 -C "laptop-2026"-a 100 sets the number of KDF rounds protecting the passphrase, which is the only thing standing between a stolen laptop and your fleet. Use a passphrase. If you own a hardware token, use that instead:
ssh-keygen -t ed25519-sk -O resident -C "token-1"Install the public half
ssh-copy-id -i ~/.ssh/id_ed25519.pub deploy@<ipv4>By hand, from a root session, if the account has no password yet:
install -d -m 700 -o deploy -g deploy /home/deploy/.ssh
install -m 600 -o deploy -g deploy /dev/null /home/deploy/.ssh/authorized_keys
cat >> /home/deploy/.ssh/authorized_keysPaste the single line, then Ctrl-D. Permissions matter more than people expect: sshd refuses a group-writable home or .ssh directory and explains itself only in the daemon log, never to the client.
Restrict the key while you are in there
Options in authorized_keys apply per key. restrict switches everything off, and then you add back what the key genuinely needs:
restrict,pty ssh-ed25519 AAAAC3Nza... deploy@laptopA key that exists to run one job should be allowed to run one job:
restrict,command="/usr/local/bin/backup-receive" ssh-ed25519 AAAAC3Nza... backupTest before you lock
Leave the first session connected. From a second terminal:
ssh -o PreferredAuthentications=publickey deploy@<ipv4> idIf that prints your uid, the key path works. If it does not, ssh -vvv on the client and journalctl -u ssh -n 50 on the server will between them say which side is unhappy. It is permissions roughly half the time and the wrong username most of the rest.
Switch passwords off
cat > /etc/ssh/sshd_config.d/20-keys-only.conf <<EOF
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitEmptyPasswords no
AuthenticationMethods publickey
EOF
sshd -t && systemctl reload sshAuthenticationMethods publickey is the belt under the braces. Even if a later drop-in quietly re-enables passwords, the daemon still refuses anything that is not a key.
Confirm from the client that the door is shut:
ssh -o PreferredAuthentications=password deploy@<ipv4>The expected result is Permission denied (publickey).
Keys at deploy time
The panel keeps a key list per account. Tick the ones you want and cloud-init writes them during first boot, which means an instance can exist for the first time with password authentication already off. Attaching the key to the order turns the ten minutes above into one.
When you lose the key
There is no identity-based recovery here, because we hold no identity. The out-of-band console is the way back: it reaches the instance over a path that never touches sshd, and from a rescue shell you can append a new key and carry on.
Keep a second key on a second machine and you will never need to read that article.