The problem

For some time now GitHub have started requiring account owners to use two factor authentication (2FA) when signing in to the GitHub web site using a browser.

A few weeks ago I received notification from GitHub that I should enable two factor authintication (2FA) for my account. This meant that, in addition to the usual username/password, I will also need a second method of authentication.

The GitHub help page on Configuring two-factor authentication provides various options for configuring the second source of the 2FA authentication. These include installing an app on my phone, use the SMS on my mobile phone, or use a third party authenticator.

I was not keen on installing yet another mobile app on my phone, or rely on the SMS service. While the SMS option works fine most of the time, it does not work if there are roaming issues when away from home! GitHub does not offer the option of email as the second authentication method, which is often offered by others as an alternative for, or in addition to, SMS based authentication.

After searching around, I came across a number of web-based and/or GUI alternatives, such as Authy and KeePassXC.

However, since my first preference in such situations is always a CLI based solution, I searched further and eventually came across the OATH Toolkit, which provides exactly what GitHub requires - Time-based One Time Password (TOTP).



The CLI based solution

The OATH Toolkit can be obtained from the Download page. It is also available as a package on various Linux distros. Once installed, you will have the main command available to you – oathtool.

When enabling the 2FA, the GitHub page will display a QR code that you are expected to scan using your mobile app. As an alternative to the QR code, there is also a setup key link near the QR code that will show a 16 character code. This is a base-32 representation of the secret information needed for the generation of the TOTP specific to your GitHub account. Copy the code and keep it in a very safe place!

When asked by GitHub, use the following command to generate the TOTP:

oathtool -b --totp KEY
123456

This will print a 6 digit number, e.g. 123456, that should be typed in the entry box.

BEWARE: If you are running the above command on a shared host, the KEY will be momentarily visible to others. To be safe, you can ask oathtool to read the KEY from the standard input:

oathtool -b --totp -
KEY
ctrl-D
123456

You will also be asked to download and save the recovery codes, copy these codes and keep them in a safe and secure place! Once you confirm that you have saved the recovery codes, your account will have 2FA enabled.

From now on in addition to the username/password you will also be asked for the 2FA key, which you can generate using the oathtool command above.



Using password-store

For those using the pass command to manage their passwords, there is a companion extension command (pass-otp) that will enable you to keep the GitHub secret key (the 16 character key) in the password store along with your other passwords.

To start using pass-otp, add your GitHub secret key to the password store:

pass otp insert -s --issuer GitHub
Enter secret for this token:
...

This will create a password-store entry and print the PASSWORD-NAME.

To obtain the TOTP during sign-in, use:

pass otp PASSWORD-NAME
123456

and type, or copy-paste, the 6 digit number in the entry box on the GitHub web page.

Or, to have it copied to the clipboard for you, use:

pass otp -c PASSWORD-NAME
Copied OTP code for PASSWORD-NAME to clipboard. Will clear in 45 seconds.

Now, it’s just a matter of pasting the code in the browser entry box.



To read further

In addition to the descriptions on the GitHub help page on Configuring two-factor authentication, you can learn further about the OATH and TOTP from the section under External Resources and Applications on the OATH Toolkit web site. It lists the relevant RFCs describing OATH and TOTP.



Epilogue

I have described above the minimal steps needed to enable 2FA for my own use. This should probably be sufficient for most use cases.

This solution works for me because I access my GitHub account via the browser on my laptop/PC, and never on a phone or tablet. It has worked fine so far :-)