The letter A styled as Alchemists logo. lchemists
Published February 1, 2022 Updated February 2, 2022
Cover
Ruby Gems Multi-Factor Authentication

As an author of several Ruby gems, I know how important it is to secure your work not only for yourself but the Ruby community at large. Thankfully, the RubyGems team has fully embraced Multi-Factor Authentication which provides an extra layer of security on top of basic login and password credentials.

You might be surprised to learn that you can add RubyGems Multi-Factor Authentication to your YubiKey for maximized security and convenience. I’m going to walk you through how to to automate this process and optionally couple this with Gemsmith if you like.

Quick Start

As an overview — or for those who want to quickly digest what this article is about — the commands to run are:

# Setup
brew install ykman
ykman oath accounts add --oath-type TOTP RubyGems:<email> <otp>

# Usage (RubyGems)
gem push example-0.0.0.gem --otp $(ykman oath accounts code --single RubyGems)

# Usage (Gemsmith)
gemsmith --publish

That’s it! …​but, if you keep reading, I’ll explain how this works.

Requirements

You’ll need the following before we proceed:

  • RubyGems - You’ll need to register an account if you’ve not done so yet.

  • YubiKey - Ensure your YubiKey is plugged into your machine.

Now you are ready to get set up.

Setup

To start, you’ll need to install the YubiKey Manager CLI. You can do this via Homebrew by running:

brew install ykman

The YubiKey Manager provides a nice interface to managing and configuring your YubiKeys. There is a lot this CLI can do but, for the purposes of this article, I’m only going to focus on account management which is all we need to communicate with RubyGems.

With ykman installed, you can explore Oath account management via a few of commands:

ykman oath accounts list
ykman oath accounts --help
ykman oath accounts add --help

You may or may not have any Oath accounts. That’s OK because were going to add one next. First off, we need your RubyGems One-Time Password key. There are two ways to obtain this information:

  • New: If you’ve not enabled Multi-Factor Authentication yet, you can do so now by following these steps. When enabling, make sure to save your key to memory — not the generated code produced by the key — because you’re going to need that next.

  • Existing: If you’ve already enabled Multi-Factor Authentication, you can obtain the key that generates your constantly rotating OTP code by copying the key from your password manager into memory. If using 1Password, for example, you just need to edit your OTP code to reveal the key.

Once you’ve obtained your key (i.e. aa5a bbbb 2ccc ddd1), make sure to strip the spaces from the key so it is one long string (i.e. aa5abbbb2cccddd1). Now we can add this key to your YubiKey as follows:

# Format
ykman oath accounts add --oath-type TOTP RubyGems:<email> <otp>

# Example
ykman oath accounts add --oath-type TOTP RubyGems:test@alchemists.io aa5abbbb2cccddd1

You can immediately verify the above worked by running the following to obtain your OTP code:

ykman oath accounts code --single RubyGems

Notice, with the above, I’m using RubyGems to name the account but you could use any string that makes sense to you. That said, use of RubyGems as the account name is currently a hard requirement for Gemsmith but I’ll expand upon that more in a moment.

Usage

Now that you’ve set up and configured your YubiKey to store and generate your RubyGems OTP codes, you can easily obtain this information by constantly running the following from the command line:

ykman oath accounts code --single RubyGems

To manually publish a version of your gem to RubyGems you’d then combine the above into a single command. Example:

gem push example-0.0.0.gem --otp $(ykman oath accounts code --single RubyGems)

Alternatively, you can use an environment variable too:

GEM_HOST_OTP_CODE=$(ykman oath accounts code --single RubyGems) gem push example-0.0.0.gem

…​but what if there was an even faster way?

Gemsmith

With Gemsmith (i.e. gem install gemsmith), the only assumption made is that you are using RubyGems as your YubiKey account label. This then means you can avoid the extra typing, shown earlier, by running a single command:

gemsmith --publish

That’s it! No long command lines or copying and pasting OTP codes. Gemsmith will not only obtain your OTP code form your YubiKey but also publish your gem securely using Multi-Factor Authentication with RubyGems. 🎉

Gemsmith can be used with any gem that supports Multi-Factor Authentication or you can use Gemsmith to build a new gem with Multi-Factor Authentication enabled for you out-of-the box:

gemsmith --build example

Be sure to check out the Gemsmith documentation to learn more, though.

Conclusion

Hopefully the above makes your life easier and speeds up the development and maintenance of your own gems. I use Gemsmith to manage all of my gems but you can always revert to typing out the shell commands or aliasing them if you like as well. Either way, stay secure!