There is a very easy way to know know which Github user is associated with your SSH key. Executing ssh -T [email protected], you will receive a greeting with your username.

❭ ssh -T [email protected]
Hi menduz! Youve successfully authenticated, but GitHub does not provide shell access.

To extract the username we can run sed over the response.

❭ ssh -T [email protected] 2>&1 | sed 's/^Hi //' | sed 's/\! .*//'
menduz

Importing GPG keys

I use my YubiKey to store both my GPG and SSH. But having the SSH working out of the box is way easier than GPG, the last requires the machine to know the public key before it can be used. And it can be either downloaded from a key server, plain .asc files, or like in my case: download it from my Github profile.

To do so, I leverage the https://github.com/{username}.gpg function.

Since we now know the username associated with the SSH in the YubiKey (the previous step), we can get the GPG keys like this:

# this step may require you to touch the YubiKeyusername=$(ssh -T [email protected] 2>&1 | sed 's/^Hi //' | sed 's/\! .*//')
❭ curl --silent "https://github.com/${username}.gpg" | gpg --import

Check it works running gpg --card-status and search for the email in the “General key info” section, it must match your GPG’s. If it doesn’t show up, make sure you are importing the same keys present in the card.

❭ gpg --card-status | grep "General key info"
General key info..: pub  ed25519/3ABC123401923E0A 2020-11-08 Agustin Mendez <[email protected]>

Setting up Git

Now that we already have our GPG and SSH working, we must configure Git to use the GPG and the mail.

To do so, the email address from the GPG will be used (which is a requirement for Github).


# Read email from the --card-status
CARD_MAIL=$(gpg --card-status | grep -Po --color=never "(?<=<).*(?=>)")

if [[ $? == 0 ]]; then
  echo "> Using mail: ${CARD_MAIL}"
  CARD_NAME=$(gpg --card-status | grep -Po --color=never "(?<=[0-9]{4}-[0-9]{2}-[0-9]{2} ).*(?= <${CARD_MAIL})")

  if [[ $? != 0 ]]; then
    echo "> ! Cannot find CARD_NAME."
    echo "> FAILED!"
  else
    echo "> Using name: ${CARD_NAME}"
    KEY_ID=$(gpg --keyid-format none --list-key "${CARD_MAIL}" | grep -Po "[A-F0-9]{40}")
    if [[ $? == 0 ]]; then
      echo "> Using key:  ${KEY_ID}"
      git config --global user.name "${CARD_NAME}"
      git config --global user.email "${CARD_MAIL}"
      git config --global commit.gpgsign true
      git config --global user.signingkey "${KEY_ID}"
      # git config --global url."ssh://[email protected]/".insteadOf "https://github.com/"

      echo "> SUCCESS!"
    else
      echo "> ! Cannot find KEY_ID"
      echo "> FAILED!"
    fi
  fi
else
  echo "> ! No known yubikey was detected."
  echo "> FAILED!"
fi

Leaking SSH keys

Did you know you are sending your identities every time you connect to an ssh server?

Be careful to not leak your keys to every place you want to connect to.

To do so, create an identity for each site you want to connect to and add the following lines to your ~/.ssh/config file:

IdentitiesOnly yes

Host github.com
  IdentityFile ~/.ssh/id_rsa_yubikey.pub

To get the public key from your SSH in the YubiKey run:

ssh-add -L | grep "cardno" > ~/.ssh/id_rsa_yubikey.pub

That is part of my https://menduz.com/bootstrap.sh script, used every time I set up a new machine or when I think that my machine was somehow compromised.