Andrew Jorgensen
It's better than bad, it's good!

SSH with Yubikey and GnuPG on chromeOS

The top search result for "ssh yubikey gpg" is a ~50 page guide with a lot of detail. This is not that, but please contact me if you use this guide for its intended purpose and run into trouble.

Since chromeOS 132, the Terminal app has switched to the wassh WASM SSH implementation. This is unfortunately incompatible with the Smart Card Connector app that let you easily use you YubiKey as your SSH key. A workaround is to use gpg-agent in a Crostini Linux session, with the YubiKey connected to the session. This can also be used for encryption and signing, but I'm not going to discuss that here.

The additional packages I had to install were libccid and scdaemon. gpg-agent should already be installed and configured to run in your user session.

sudo apt update
sudo apt install libccid scdaemon

GPG should run scdaemon when it needs it, so it should just work.

The only additional configuration I really had to do was to configure the SSH auth socket and the GPG agent tty.

export SSH_AUTH_SOCK=$(gpgconf --list-dirs agent-ssh-socket)
GPG_TTY=$(tty) gpg-connect-agent updatestartuptty /bye > /dev/null

You can add the above to the end of .profile so that it will be configured correctly whenever you run Crostini.

Then you need to connect your YubiKey to your Linux session through the notification or through the system Settings app. I also had to uninstall the Smart Card Connector app because if it has a hold on your YubiKey, neither Linux nor Android can have it, and chromeOS won't warn you that it's not actually connected.

With all that done, you should be able to run gpg --card-status to verify that the YubiKey is connected, and ssh-add -L to verify that SSH can see your YubiKey as well.

When you ssh to a computer that wants your YubiKey for authentication, you should be prompted to enter your PIN. Mine defaulted to pinentry-curses which is more UI than I normally want, but I also prefer to spend as little effort configuring things as possible, so it's good enough for me.