SSH key hygiene for homelabs: what's in your authorized_keys?

Every homelab accumulates SSH keys. The laptop you replaced three years ago left one. The key you made for a one-off deployment never got removed. The key your co-worker had for a shared project is still active. This post is about finding them, making sense of them, and rotating without locking yourself out.

What authorized_keys actually contains

Each line is one public key that can log in as the owning user. Format:

[options] keytype base64blob [comment]

Example:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINfT Noxen@macbook-2024

The comment at the end is free-form — ssh-keygen defaults it to user@hostname but that's a convention, not a rule. You can't trust the comment to be accurate; treat it as a hint.

Audit every host in one go

For every user that has an authorized_keys:

for user in $(awk -F: '$3>=1000 {print $1}' /etc/passwd) root; do
  auth=$(eval echo ~$user/.ssh/authorized_keys)
  if [ -f "$auth" ]; then
    echo "=== $user ==="
    ssh-keygen -lf "$auth"
  fi
done

Output looks like:

=== Noxen ===
256 SHA256:1W6rCisKaoOAdGtsRfI90UySDBhwDJDivjE21pUiB1A Noxen@macbook-2024 (ED25519)
256 SHA256:ABCxxx...                                    vagrant (ED25519)

Two keys, two fingerprints. If you can't tell what each one is for from the fingerprint alone — they're orphans. Remove them.

Compare against the keys you think you have

On your laptop:

ssh-add -l       # keys currently loaded in ssh-agent
ls ~/.ssh/*.pub  # keys on disk

The fingerprint of ~/.ssh/id_ed25519.pub should match exactly one entry in every authorized_keys across your fleet. Any fingerprint on a remote host that doesn't correspond to a key on your laptop is a candidate for deletion.

Signs a key has gone stale

The painless rotation

  1. Generate a fresh Ed25519 keypair on your laptop:
    ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_2026 -C "Noxen@macbook-2026"
  2. Copy the new key to every host alongside the old one — don't remove the old one yet:
    for host in $(awk '/^Host / && !/*/ {print $2}' ~/.ssh/config); do
      ssh-copy-id -i ~/.ssh/id_ed25519_2026.pub "$host"
    done
  3. Test: ssh -i ~/.ssh/id_ed25519_2026 host. If it works from everywhere, carry on.
  4. Remove the old key from every host. Easiest way: edit ~/.ssh/authorized_keys on each box to delete the old line, or use ssh rm loops if you trust yourself to script it.
  5. On the laptop, update ~/.ssh/config's IdentityFile entries and delete the old keypair.

Noxen makes this visible

Every scan pulls ~/.ssh/authorized_keys per enrolled user and surfaces:

It doesn't auto-rotate — that's a destructive operation we leave to the operator. But it makes the "which keys exist" question a one-look answer instead of a bash loop.