Skip to content

AWS credential_process utility to assume AWS IAM Roles with Yubikey Touch and Authenticator App TOPT MFA to provide temporary session credentials; With encrypted caching and support for automatic credential refresh.

License

Notifications You must be signed in to change notification settings

joni3k/vegas-credentials

 
 

Repository files navigation

🚧 🚧 🚧 Work-in-Progress 🚀 ⁉️ Publish Plan
Things may break without any prior notice at any given v0.x.x version: So do not use this for anything critical, but feel free to test this out and give feedback! After some testing, depending on the amount of bugs/issues/feedback, I'm hoping to release v1.0.0 during November 2021. No commitments though!

Vegas Credentials

Much like spending a week in Las Vegas at AWS re:Invent, using multiple AWS tools (SDKs, CLI, CDK, Terraform, etc) via command-line to assume IAM roles in different accounts with Multi-Factor Authentication can be an exhausting experience: vegas-credentials aims to simplify the credential process! And just like you shouldn't stay too long in Las Vegas at once, this tool only deals with temporary sesssion credentials.

Vegas Credentials is an utility with smooth user experience that plugs into AWS credential_process to assume IAM Roles with TOPT MFA (with optional Yubikey Touch support) to fetch, cache and refresh assumed temporary session credentials.


build Coverage Maintainability Rating Security Rating Vulnerabilities


Features Overview Get Started Yubikeys Configuration Examples Why? Design

Features

  • Plugs into AWS credential_process: If you're unfamiliar with AWS credential_process, this AWS re:Invent video explains it very well

  • Supports automatic temporary session credential refreshing for tools that understand session credential expiration

  • Supports Role Chaining

  • Works out-of-the-box with most tools such as AWS CLI, most AWS SDKs, AWS CDK, Terraform...

  • Encrypted Caching of session credentials to speed things up & to avoid having to input MFA token code for each operation

  • Supports both Yubikey Touch or Authenticator App TOPT MFA simultaneously:

    • For example you can default to using Yubikey, but if don't have the Yubikey with you all the time and also have MFA codes in an Authenticator App (such as Authy for example)
    • You may just touch the Yubikey or manually type the token code (via GUI Prompt Dialog or CLI stdin) – which ever input is given first will be used
  • Smooth Yubikey integration:

    • Just tap your physical key: No need to manually type or copy-paste MFA token code
    • Supports multiple Yubikey devices
  • Fast & Cross-Platform: Built with Go and supports macOS, Linux and Windows operating systems with x86_64 & arm64 (e.g. Apple M1) architectures


By design, this tool does not support:



Overview

diagram


Get Started

  1. Install vegas-credentials via one of the following:

    Homebrew (MacOS/Linux)
    • Requires brew-command
    • Install:
      brew tap aripalo/tap
      brew install vegas-credentials
      
      # Verify installation
      vegas-credentials --version

    Scoop (Windows)
    • Requires scoop-command
    • Install:
      scoop bucket add aripalo https://github.com/aripalo/scoops.git
      scoop install aripalo/vegas-credentials
      
      # Verify installation
      vegas-credentials --version

    NPM (MacOS/Linux/Windows)

    DOES NOT CURRENTLY WORK!

    • Requires node-command (v14+)
    • Install:
      npm install -g vegas-credentials
      
      # Verify installation
      vegas-credentials --version


  2. Configure you source profile and its credentials, most often it's the default one which you configure into ~/.aws/credentials:

    # ~/.aws/credentials
    [default]
    aws_access_key_id = AKIAIOSFODNN7EXAMPLE
    aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
  3. TODO

    # ~/.aws/config
    [default]
    mfa_serial = arn:aws:iam::111111111111:mfa/FrankSinatra
  4. Configure your target profile with credential_process into ~/.aws/config:

    # ~/.aws/config
    [profile frank@concerts]
    credential_process = vegas-credentials assume --profile=frank@concerts
    vegas_role_arn=arn:aws:iam::222222222222:role/SingerRole
    vegas_source_profile=default
    
    # You may also provide any other additional standard AWS configuration, such as:
    region = us-west-1
    duration_seconds = 4383
    role_session_name = SinatraAtTheSands
    external_id = 0093624694724

    Note: role_arn & source_profile must be prefixed with vegas_ to prevent AWS tooling to ignore credential_process setting and to prevent Terraform failing.

  5. Use any AWS tooling that support ini-based configuration with credential_process, like AWS CLI v2:

    aws sts get-caller-identity --profile frank@concerts

Yubikeys

To use Yubikeys:

  1. You must have at least one Yubikey Touch device with OATH TOPT support (Yubikey 5 or 5C recommended).

  2. Install ykman CLI

  3. Set up Yubikey as Virtual MFA device in AWS IAM - Not U2F MFA!

  4. Think of backup strategy in case you lose your Yubikey device, you should do at least one of the following:

    • During Virtual MFA device setup also assign Authenticator App such as Authy for backup
    • If you own multiple Yubikey devices, during Virtual MFA device setup also configure the second Yubikey and once done, store it securely
    • Print the QR-code (and store & lock it very securely)
    • Save the QR-code or secret key in some secure & encrypted location
  5. When configuring your Yubikey, use arn:aws:iam::<ACCOUNT_ID>:mfa/<IAM_USERNAME> (i.e. MFA device ARN) as the Yubikey OATH account label:

    ykman oath accounts add -t arn:aws:iam::<ACCOUNT_ID>:mfa/<IAM_USERNAME>
  6. Configure vegas_yubikey_serial into ~/.aws/config:

    # ~/.aws/config
    [default]
    mfa_serial = arn:aws:iam::111111111111:mfa/FrankSinatra
    vegas_yubikey_serial = 12345678

    Optionally you may configure vegas_yubikey_label if you used something else than arn:aws:iam::<ACCOUNT_ID>:mfa/<IAM_USERNAME> as the OATH account label (though not recommended).


Configuration

Configuration for the most part happens in ~/.aws/config ini-file, but there are some command-line flags and environment variables that you may want to use sometimes.

Source Profile Configuration

Option Description
mfa_serial Required: The ARN of the Virtual (OATH TOPT) MFA device used in Multi-Factor Authentication.
vegas_yubikey_serial Required if using Yubikey: Yubikey Device Serial to use. You can see the serial(s) with ykman list command. This enforces the use of a specific Yubikey and also enables the support for using multiple Yubikeys (for different profiles)!
vegas_yubikey_label Use only if you have any other value than the AWS MFA Device ARN as oath account label! Yubikey oath Account Label to use. You can see the available accounts with ykman oath accounts list command. Set the account label which you have configured your AWS TOPT MFA!

Example:

# ~/.aws/config
[default]
mfa_serial = arn:aws:iam::111111111111:mfa/FrankSinatra
vegas_yubikey_serial = 12345678

Target Profile Configuration

Option Description
credential_process Required: To enable this tool, set the value as vegas-credentials assume --profile <my-profile>. Value of my-profile must match the profile name in ini-section title, e.g. [profile my-profile].
vegas_role_arn Required: The target IAM Role ARN to be assumed.
vegas_source_profile Required: Which credentials (profile) are to be used as a source for assuming the target role.

Example:

# ~/.aws/config
[profile frank@concerts]
credential_process = vegas-credentials assume --profile=frank@concerts
vegas_role_arn=arn:aws:iam::222222222222:role/SingerRole
vegas_source_profile=default

# You may also provide any other additional standard AWS configuration, such as:
region = us-west-1
duration_seconds = 4383
role_session_name = SinatraAtTheSands
external_id = 0093624694724

Command-line Flags

Flag Description
--help Prints help text
--profile Required: Which AWS Profile to use from ~/.aws/config: Value (for example my-profile) must match the profile name in ini-section title, e.g. [profile my-profile]
--disable-dialog Disable GUI Dialog Prompt
--disable-mandatory-refresh Disable Session Credentials refreshing if expiration within 10 minutes (as defined in Botocore)
--hide-arns Hide IAM Role & MFA Serial ARNS from output (even on verbose mode)
--verbose Verbose output
--debug Prints out various debugging information
--no-color Disable colorful fancy output

Example:

vegas-credentials assume --profile=frank@concerts --verbose --no-color

... though you shouldn't really call this tool directly yourself, but instead configure it as credential_process in ~/.aws/config.

Environment Variables

Option Description
NO_COLOR Disable colorful fancy output, see also --no-color CLI flag
VEGAS_CREDENTIALS_NO_COLOR Disable color only for this tool (not for your whole environment )
TERM=dumb Another way to disable colorful fancy output

Examples

Using with AWS SDKs

Often times you may not want to define the profile within the application code, since the application code most often will be ran without profile in cloud. You may circumvent this by setting the profile via AWS_PROFILE environment variable. Most AWS SDKs should support this. Example with running a NodeJS based script (that does something with AWS SDK):

AWS_PROFILE=frank@concerts ts-node src/index.ts

By default, the SDK checks the AWS_PROFILE environment variable to determine which profile to use. If the AWS_PROFILE variable is not set in your environment, the SDK uses the credentials for the [default] profile. To use one of the alternate profiles, set or change the value of the AWS_PROFILE environment variable. For example, given the configuration file shown, to use the credentials from the work account, set the AWS_PROFILE environment variable to work-account (as appropriate for your operating system).

AWS SDK v3 docs

Role Chaining

This tool also supports role chaining - given that the specific AWS tool your using supports it - which means assuming an initial role and then using it to assume another role. An example with 3 different AWS accounts would look like:

role-chaining


Assuming correct IAM roles exists with valid permissions and trust policies:

  1. Assuming you have the following configuration already:

    # ~/.aws/credentials
    [default]
    aws_access_key_id = AKIAIOSFODNN7EXAMPLE
    aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
    # ~/.aws/config
    [default]
    aws_mfa_device = arn:aws:iam::111111111111:mfa/FrankSinatra
    
    [profile frank@concerts]
    credential_process = vegas-credentials assume --profile=frank@concerts
    vegas_role_arn=arn:aws:iam::222222222222:role/SingerRole
    vegas_source_profile=default
  2. Configure another role with standard role_arn and source_profile:

    # ~/.aws/config
    [profile frank@movies]
    role_arn=arn:aws:iam::333333333333:role/ActorRole # Important: NO prefix here!
    source_profile=frank@concerts # Important: NO prefix here!
  3. Do some chaining:

    aws sts get-caller-identity --profile frank@movies

Terraform

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

# Again, nothing special here, just normal profile configuration…
provider "aws" {
  profile = "frank@concerts"
  region  = "eu-west-3"
}

data "aws_region" "current" {}

output "album_name" {
  value = "Sinatra & Sextet: Live in ${
    replace(
      regex("[a-zA-Z]+\\)$", data.aws_region.current.description),
      ")",
      ""
    )
  }"
}

Why yet another tool?

Reasons

There are already a bazillion ways to assume an IAM Role with MFA, but most existing open source tools in this scene either:

  • export the temporary session credentials to environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN)
  • write new sections for “short-term” credentials into ~/.aws/credentials (for example like aws-mfa does)

The downside with those approaches is that using most of these tools (especially the ones that export environment variables) means you lose the built-in ability to automatically refresh the temporary credentials and/or the temporary credentials are “cached” in some custom location or saved into ~/.aws/credentials.

This tool follows the concept that you should never put temporary credentials into ~/.aws/credentials and also provides a mechanism to automatically refresh session credentials (if the AWS tool you use supports that).

Most AWS provided tools & SDKs already support MFA & assuming a role out of the box, but what they lack is a nice integration with Yubikey Touch, requiring you to manually type in or copy-paste the MFA TOPT token code: This utility instead integrates with ykman Yubikey CLI so just a quick touch is enough!

Also with this tool, even if you use Yubikey Touch, you still get the possibility to input MFA TOPT token code manually from an Authenticator App (for example if you don't have your Yubikey on your person).

Then there's tools such as AWS CDK that does not support caching of assumed temporary credentials, requiring the user to input the MFA TOPT token code for every operation with cdk CLI – which makes the developer experience really cumbersome.

To recap, most existing solutions (I've seen so far) to these challenges either lack support for automatic temporary session credential refreshing, cache/write temporary session credentials to suboptimal locations and/or don't work that well with AWS tooling (i.e. requiring one to create “wrappers”):

This vegas-credentials is yet another tool, but it plugs into the standard credential_process AWS configuration so most of AWS tooling (CLI v2, SDKs and CDK) will work out-of-the-box with it and also support automatic temporary session credential refreshing.

Alternatives

There are many great existing solutions out there that solve similar problems and I've tried to learn from them as much as I can. This tool that I've built is definitely not better than for example 99designs/aws-vault in many scenarios as it has a lot more features, more contributors and been around some time. Instead the comparison below focuses on the specific use case this tool tries to solve (i.e. providing a nice UX for assuming a role with MFA using credential_process to support as many AWS tools as possible without having to use wrapper scripts).

Feature/Info aripalo/vegas-credentials 99designs/aws-vault broamski/aws-mfa meeuw/aws-credential-process
Github Stats GitHub Repo stars
GitHub last commit
GitHub Repo stars
GitHub last commit
GitHub Repo stars
GitHub last commit
GitHub Repo stars
GitHub last commit
credential_process
with MFA + Assume Role
[*2] [*4]
Automatic Temporary Session Credential Refresh [*3] [*5]
Yubikey ✅ ✅ [*1] [*1] [*6] [*10]
Cache Encryption [*7]
Cache Invalidation on config change ✅ ? [*8]
Cached Performance ⚡️
<100ms[*11]
⚡️
<50ms
⚡️
[*9]
🐢
>400ms[*11]
Comprehensively Unit Tested ?
Installation methods brew, scoop, npm brew, port, choco, scoop, pacman, pkg, zypper, nix-env, asdf pip brew, pip

Please, correct me if I'm wrong above or there's any other good alternatives!

Notes

99designs/aws-vault

  1. Yubikey support in 99designs/aws-vault is not perfect:

    • Using multiple Yubikeys is cumbersome due to having to pass in Yubikey device serial as environment variable for each command – vs. this tool allows setting device serial via configuration per profile (no need to remember the serial for each Yubikey).
    • Uses deprecated ykman commands.
    • See also point 2 about credential_process, assumed roles and Yubikeys.
  2. Does not seem to play well with credential_process:

  3. This pretty much relates to point 1: For AWS tools to automatically request refreshed credentials, the credentials need to be provided via either the multiple standard methods or via credential_process.

broamski/aws-mfa

  1. Works differently by writing temporary session credentials into ~/.aws/credentials, so therefore no credential_process support at all.

  2. If temporary session credentials written into ~/.aws/credentials by broamski/aws-mfa are expired, AWS tools will fail and you must invoke aws-mfa command manually to fetch new session credentials. There is no (automatic) way for AWS tools to trigger aws-mfa command.

  3. You may use Yubikey, but it requires you to manually copy-paste the value from ykman or Yubikey Manager GUI. No "touch integration".

  4. Temporary session credentials are written in plaintext into ~/aws/credentials. Besides being available as plaintext, it pollutes the credentials file.

  5. Configuration is only provided via flags to aws-mfa CLI command, so each time you execute aws-mfa it will use the flags provided. But, the gotcha is that again you need to execute aws-mfa manually always.

  6. As temporary session credentials (or "short-term" as aws-mfa calls them) are stored as plaintext into ~/aws/credentials, there is no delay since AWS tools can directly read them from that file.

meeuw/aws-credential-process

  1. Does not support multiple Yubikey devices.

  2. Performance

    Hyperfine benchmark for retrieving cached temporary session credentials:

    perf


Design

Cache Mechanism

This tool caches temporary session credentials to disk. In the background it uses dgraph-io/badger which is a fast SSD-optimized key-value store for Go and importantly supports Time-to-Live attributes for data (useful for temporary session credential expiration).

The data is stored into the key-value store with AES-256-CTR encryption. The encryption secret is derived from the environment (system boot time, hostname and user UID). So this is not a 100% secure setup, but it's slightly “better” compared to what broamski/aws-mfa does or how AWS CLI caches to ~/.aws/cli/cache: At least it provides “security by obscurity” solution against rogue scripts that might try to steal your credentials. And then again, it's only caching temporary session credentials – which you should aim to keep short-lived!

Reason why it caches temporary session credentials in the first place is to create a better user experience with AWS tools that don't support temporary session credential caching with assumed roles.

By default, the cached data is invalidated if the environment changes (system boot time, hostname and user UID), but this is okay since this tool will then query STS for new temporary session credentials and add them to cache.

Also this tool invalidates cached credentials if their expiration time is within 10 minutes and retrieves new ones. This functionality matches to botocore. You may disable this with --disable-mandatory-refresh CLI flag.

Never touch ~/.aws/credentials

TODO

Never export credentials to environment

TODO

About

AWS credential_process utility to assume AWS IAM Roles with Yubikey Touch and Authenticator App TOPT MFA to provide temporary session credentials; With encrypted caching and support for automatic credential refresh.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 96.6%
  • JavaScript 2.5%
  • Other 0.9%