Import SSH Keys Safely with ssh-import-id

Chasing someone's public key through a Slack thread is the slow way; ssh-import-id pulls it straight from their GitHub or Launchpad account instead. It adds published public keys to an authorised keys file, and this guide covers previewing what it will add, checking what actually changed, and removing keys it imported. Examples use Ubuntu's package version 5.11-0ubuntu2.24.04.1, as installed on this machine.

Allow about ten minutes for a preview and verification, plus whatever time it takes to confirm the online account name. You need an installed ssh-import-id, network access to the provider, and permission to read or write the destination file. A real import changes SSH login access, so confirm the identity before you run one for real.

1. Check the installed command

Start with read-only checks, none of which need elevated privileges:

$ command -v ssh-import-id
/usr/bin/ssh-import-id
$ dpkg-query -W -f='${Package} ${Version}\n' ssh-import-id
ssh-import-id 5.11-0ubuntu2.24.04.1
$ ssh-import-id --help
usage: ssh-import-id [-h] [-o FILE] [-r] [-u USERAGENT] USERID [USERID ...]

The package also installs ssh-import-id-gh and ssh-import-id-lp, but the main command is easier for a mixed list since each identity can carry its own gh: or lp: prefix.

Checkpoint: if command -v finds nothing, stop and install the package through your normal system-management process. Do not copy a random script into a system bin directory as a shortcut.

2. Choose the provider and identity carefully

The installed command supports gh: for GitHub and lp: for Launchpad. An unprefixed identity uses the configured default: on this Ubuntu install, /etc/ssh/ssh_import_id holds a JSON URL pointing at Launchpad's HTTPS key endpoint, so an unprefixed name normally means Launchpad, and the manual confirms Launchpad is also the fallback when no configuration exists at all.

Use an explicit prefix in scripts and notes so a later review is never ambiguous:

$ ssh-import-id -o - gh:ACCOUNT_NAME
$ ssh-import-id -o - lp:ACCOUNT_NAME

Replace ACCOUNT_NAME with the exact public account name. -o - sends fetched keys to standard output instead of touching ~/.ssh/authorized_keys. An account with no published keys produces nothing to import, and a misspelled one can produce a provider error.

Security boundary: the provider account is the trust decision here. Review its public keys on the provider's own site, and never import an identity just because someone sent you a username. Never enter a private key, password or access token as the user ID.

3. Preview the exact key material

Preview to a temporary file in a private directory, then inspect it. This is an ordinary user operation:

$ preview_dir=$(mktemp -d)
$ chmod 700 "$preview_dir"
$ ssh-import-id -o - gh:ACCOUNT_NAME > "$preview_dir/keys"
$ sed -n '1,12p' "$preview_dir/keys"
$ ssh-keygen -lf "$preview_dir/keys"
256 SHA256:... ACCOUNT_NAME@github/123456 (ED25519)

Log messages normally go to standard error while the key stream goes to standard output; the fingerprint above is illustrative and yours will differ. If ssh-keygen -lf rejects the file, do not import it. Check the provider name and the error first.

Then clean up the preview:

$ rm -f "$preview_dir/keys"
$ rmdir "$preview_dir"

That only removes the temporary preview. It never touches an authorised keys file.

4. Import the key as the login user

Run the import as the account that should actually receive SSH access. This is normally unprivileged:

$ ssh-import-id gh:ACCOUNT_NAME
2026-09-27 04:00:00,000 INFO [1] SSH keys [Authorized]

Timestamp, fingerprint and count will all vary. The tool appends valid fetched keys to ~/.ssh/authorized_keys, creates the parent directory if needed, and adds a trailing comment such as # ssh-import-id gh:ACCOUNT_NAME. It identifies duplicates by fingerprint, so running the same import twice should report an already-authorised key rather than append a second copy.

Never add sudo out of habit. Running as root targets root's own ~/.ssh/authorized_keys, not the current user's, unless you explicitly point it elsewhere. Save elevated privileges for when the destination is deliberately a protected file owned by another account, and review the path before proceeding.

Warning: this changes who can log in. Keep an existing session open while testing the new access, and never replace the file with the fetched output instead of appending to it: that can wipe out unrelated recovery keys.

5. Verify the destination and the label

Check the file the command actually changed:

$ keyfile="$HOME/.ssh/authorized_keys"
$ test -f "$keyfile" && echo "authorised keys file exists"
authorised keys file exists
$ grep -F -- '# ssh-import-id gh:ACCOUNT_NAME' "$keyfile"
ssh-ed25519 AAAA... ACCOUNT_NAME@github/123456 # ssh-import-id gh:ACCOUNT_NAME
$ ssh-keygen -lf "$keyfile"

The grep line above is shortened for display. A matching comment alone is not proof of valid key material; ssh-keygen -lf should also be able to read the file cleanly. File missing? Check HOME and the account are what you expect. No matching keys imported? Fix the identity or publish a key at the provider before retrying.

6. Import more than one identity

Pass several user IDs in one invocation, prefixing each when providers are mixed:

$ ssh-import-id gh:FIRST_ACCOUNT lp:SECOND_ACCOUNT
2026-09-27 04:00:00,000 INFO [2] SSH keys [Authorized]

Count and messages depend on each account. A failure for one user ID can leave earlier successful imports standing, so check the file after a multi-user run rather than assuming it was all-or-nothing.

7. Remove keys imported for one identity

Removal is security-sensitive, so list the labelled lines first and confirm the label matches the account you actually intend to revoke:

$ grep -F -- '# ssh-import-id gh:ACCOUNT_NAME' "$HOME/.ssh/authorized_keys"
ssh-ed25519 AAAA... ACCOUNT_NAME@github/123456 # ssh-import-id gh:ACCOUNT_NAME

Then run the matching import with --remove:

$ ssh-import-id --remove gh:ACCOUNT_NAME
2026-09-27 04:00:00,000 INFO [0] SSH keys [Removed]

This removes only lines ending with the exact tool label. It leaves an unlabelled copy of the same public key untouched, and never removes keys labelled for another identity. Verify the result:

$ if grep -F -- '# ssh-import-id gh:ACCOUNT_NAME' "$HOME/.ssh/authorized_keys"; then
    echo 'label still present'
  else
    echo 'label removed'
  fi
label removed

Removed the wrong labelled keys? Recovery just means importing that identity again, provided its public keys are still published. Keep a separate, tested administrative key until access is confirmed either way.

Common traps

Done means