Adjusting To GitHub's 2FA
When GitHub announced the introduction of 2FA, I decided to wait for a few days before trying it (you know, shutting yourself out of your own account is like closing the door with your keys still on the kitchen table: it’s not funny).
Setting up 2FA is easy and quick; the only thing I’d like they changed is the fact that those recovery codes should not be still accessible in the settings section, imho. But I’m digressing.
The first thing to notice is that, unfortunately, the most famous Android applications for GitHub (the official application, Hubdroid and Octodroid) do not currently support 2FA and thus they’re unable to authenticate after you’ve activated it; easy workaround: authenticate them before switching 2FA on.
Interacting with the APIs is a bit different: Basic Authentication is still usable, but you need to pass the OTP in a specific header and if you have a very long script with multiple commands, that OTP is going to expire too soon; authenticating via OAuth is still the same however.
At this point I started playing a bit with the latest Octokit gem, which changed quite a lot starting with version 2.0.0, and wrote some toy scripts.
The first toy was this:
If you’d already activated 2FA, it asked you an OTP and retried. It worked,
but that OTP expires quickly and you’d have to add the X-GitHub-OTP
header
to each request. Unrealistic.
Using OAuth2 tokens is much better, so my second toy first used Basic Authentication to create a brand new token and then used it to iterate over some repositories:
This second toy assumes you’re using 2FA and creates a lot of garbage over time in your Personal Access Tokens panel: those tokens are clearly labeled as “Disposable”, but it’s not funny to have to remove tons of tokens after some months of use, is it?
Maybe reusing a single token is better, so my third toy used Basic Authentication to retrieve an existing token, aptly named “Toy 3”, from GitHub and then used it over and over again:
Storing a token locally instead of grabbing one from GitHub (and thus having
to type a new OTP each time you have to use a script) is probably better.
Where could it be stored? .netrc
could be an option (it’s a portable
solution, fully supported by Octokit gem), but… These days I use a Mac, so
after a while I started thinking that using OS X’s keychain is, maybe,
slightly better than having your token in a plain text file and so I added a
token to my default keychain with some optional flags to clearly make it stand
out:
Then my fourth toy used the security
command to retrieve that token:
I’m not 100% sure that the find-generic-password
sub-command has the -w
flag even in older OS X releases; anyway, when this fourth toy ran, I was
asked to grant security
access to the token (because of that -T
flag
security
was not automatically authorized) and then the script went on
without issues.
I purposely used the -D
flag to specify a “custom” kind instead of mixing
the token with the other application passwords when creating the item and
tried to identify accurately the entry for find-generic-password
: changing
values for -a
and -s
it should be possible to add more than one token, if
necessary.
So, in the end, I can say that using GitHub’s APIs with 2FA is slightly more inconvenient, but not too much to force someone to turn it off and that I spent some pleasant time playing with the Octokit gem and getting to know it a little bit better.