GitHub 2FA using a CLI
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 :-)