Working all day via the AWS CLI or on the AWS API using Multi Factor Authentication (MFA), one quickly wishes for a more elegant way of providing a second factor. Prolonging the validity of session tokens is one option, another one is to skip entering the OTP entirely.

We already showed you at https://tech.europace.de/pro-tip-working-with-aws/ how to assume different roles using profiles with awsume (https://github.com/trek10inc/awsume). awsume can interactively ask for your token or reads it from a command line parameter. Either way, the token will be used to create or refresh an AWS session and configuring your environment with all necessary credentials.

If you’re not so much into installing Python packages - just like me -, you either find a way to encapsulate everything in a Docker container, or you try to find other tools. The alternative awsu (https://github.com/kreuzwerker/awsu) allows a similar flow like awsume does. There are little twists, though: First, awsu ist written in Golang, which eases lokal installation without dependency conflicts. Second, and now we’re at the main topic of this article, awsu can use your YubiKey to create a new virtual MFA device on your AWS account and delegate token retrieval to the YubiKey instead of having to manually entering it on every session refresh.

Setup

In fact, usage is straight forward and you can find everything perfectly described in the project’s readme (https://github.com/kreuzwerker/awsu#installation), so we’ll keep it short.

You should prepare your $HOME/.aws/config and $HOME/aws/credentials with your profile config, and you should ensure that your account doesn’t have any MFA device configured, because AWS doesn’t allow multiple devices, yet. Please also put your YubiKey into your computer, so that awsu can access it.

The first setup requires a single step. awsu only needs your IAM username and the profile name. Heads up: please see the notes at the end of this article for a hint about proper use of profile names.

# Initial registration of a YubiKey based MFA device
./awsu register user.name -p profile_name

The command performs several actions under the hood, e.g. creating a new virtual MFA device on your AWS account and writing the OTP secret to your YubiKey’s OTP slot.

When the command finishes with success, you’ll see a big QR code with the OTP secret on your terminal, which you can optionally save in your usual authenticator app (e.g. Google Authenticator). Well, do it, because you’ll need it when trying to login via web browser.

Usage

Similar to awsume, awsu also allows two major modes: either modifying the current environment (eval $(awsu -p profile_name)) or working as kind of sudo by running your actual task in a sub-process with modified environment:

# Example using `env` in a sub-process
awsu -p profile_name -- env | grep AWS

awsu will read your settings for profile_name, ask the YubiKey for a valid OTP and update or create a AWS session. By default, the session details will be cached in your user home at $HOME/.awsu/sessions/profile_name.json, so that subsequent commands can re-use a valid session.

The best thing: in the morning, when your session has certainly become invalid, you only need to put the YubiKey into your computer and run awsu -p profile_name -- your_morning_routine.

No manual token input anymore. It just works.

Further notes

  • There’s no official Windows release, yet, but thanks to Golang, awsu can be cross compiled easily.
  • Depending on your local setup you currently have to add the prefix profile to profile_name, until the related pull request is merged: https://github.com/kreuzwerker/awsu/pull/43. So, the examples above should look like this: awsu -p 'profile profile_name' -- ....
  • You’re not required to touch the YubiKey during OTP retrieval, which is another pending discussion at https://github.com/kreuzwerker/awsu/pull/42.
  • If you forgot to save the QR code with the seed in your authenticator app, you can still use the following command to generate OTPs on the command line: awsu -p profile_name token && echo.