Benjamin Sago / ogham / cairnrefinery / etc…

Technical notes Always comment your SSH keys

One day, several years ago, I was clearing out my office desk. Inside, I found a USB stick containing (among other things) two files with names you have almost certainly seen before: id_rsa and id_rsa.pub.

I had absolutely no idea what they were for. Did they give me access to some critical work server that I might need to access again in an emergency? Was this a set of keys so secret even I had forgotten about it, in case I needed to access my own personal servers if my house burns down? Or did I get distracted immediately after creating them, and they’re keys to nowhere?

I still have no idea what they were for, but looking at the comment inside the public key, which contained my personal machine’s name, I could see that it wasn’t anything to do with work — and because I was 100% certain that I could access every one of my personal servers without the key, I could go ahead and delete it.

But I still had some questions. When was this key generated? Its mtime was suspiciously new. And what was the key for? I couldn’t tell by its name or comment.

From that moment on, I resolved to never generate a key that didn’t conform to my commenting system.

What to put in a comment

There are three things I encode in my SSH keys’ comments:

  1. An abbreviated name of the computer I’m generating it for.
  2. The purpose of the key — which machines it’s going to access.
  3. The current year and month.

These pieces of data, combined, means that if I ever find any more mysterious SSH keys on USB sticks in my office drawer, I’ll know exactly what they’re for, without having to check each and every server to see which keys are authorised.

Comment at time of creation

Something that catches a lot of people out is that the comment is stored in both the public key and the private key. It’s sneaky because if you open the public key in your text editor, you’ll see the comment stored in plain text, but if you open the private key, all you’ll see is some PEM-encoded data.

You can extract the comment by passing the -y flag to ssh-keygen. This generates public key from a private one, which will be complete with comment:

ssh-keygen -y -f example
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMQgWbYbFd859+PPNRD4yQ1wjyAQVrraUPEnR0GMYdU6 I am a comment!

So you should always specify your comments by passing the -C flag to ssh-keygen, rather than leaving it as the default and editing the public key file immediately after.

Beware: comments are sometimes public

One thing you need to be aware of when commenting your SSH keys is that certain sites will consider both the public key data, and its comment, as public.

GitHub, for example, publicises the keys of each and every user. Here are mine! It’s even possible to use this list of keys to tell whether a GitHub user has attempted to SSH into your server by checking the keys it sends, as Filippo Valsorda, Go security lead, once did. This creeps a lot of people out, as it seems like private data is being made public — but your public SSH keys really should be treated as though they’re public. The private keys are the ones you need to keep private.

Whether to make the comment public is a slightly different question. If you look at my keys from GitHub, you’ll see that the comment is not included in the response. Sourcehut, on the other hand, has opted to include the comments, so if you browse my keys, you’ll see the comments I used when generating them. This is why I have abbreviated the device names down to w, d, s, and r.

I don’t think it’s right for the comment to be made public like this when the default OpenSSH behaviour is to include your computer’s name — something that feels private, even if it may be completely harmless putting it out there — but it happens, so it remains something you should be aware of.