AWS Vault with Yubikey


2 min read


It's been a while I'm using aws-vault to manage my AWS credentials for accessing the different client accounts. It has been quite comfortable, regardless of the setup the clients choose for their users. However, there are 3 places which I'm trying to improve my own development experience:

  1. Requirement of 2FA authentication
  2. SSO Login through a browser (to get access over shell)
  3. Session duration

Today I managed to resolve the first one (to some extent), and here is how:


Well, I understand how the second-factor authentication contributes to keeping me secure. However, as a developer, it can be quite distracting to find your phone and go through the authenticator app to find the code you need to type to be able to continue your work (yeah, call me lazy!).

So, to solve this issue, I was using the 2fa CLI application, so I had this code with the comfort of my CLI. But:

  1. 2fa stores the secret key in a plain text file in ~/.2fa. Meaning anyone cating it can regenerate my tokens (more of a silly practice than a security risk, as 2fa is not the only layer of protection).
  2. I need to have a journey between terminal/tmux windows to get this code in my clipboard (told you already, I'm lazy!).


Thanks to DataChef, we've switched to using yubikey devices, for our second-factor authentication. And I was wondering if it can help me to cover these concerns!

Well, it is. All I need to do is to provide it with the secret key (either resync, or extract it from one of the registered devices), and after that, whenever needed just touch the key and it's done:

In Action


Using this so far, I've faced 2 small glitches, which confused me at first:

  1. When a token has been used, it's not possible to reuse it for a different session on AWS. This I couldn't face before (tbh, the use-case is quite rare), because the context switch was probably taking me around 30 seconds (the time window for token refresh)!
  2. av aliases for zsh-aws-vault plugin (link to my fork), need a bit of refactoring to be able to understand --prompt parameter. Otherwise, I need to provide AWS_VAULT_PL_MFA=yubikey as an environment variable, you can see why:
avsh () {
        case ${AWS_VAULT_PL_MFA} in
                (inline) aws-vault exec -t $2 $1 -- zsh ;;
                (yubikey) totp=${2:-$1} 
                        aws-vault exec -t $(ykman oath code --single $totp) $1 -- zsh ;;
                (*) aws-vault exec $1 -- zsh ;;