Back to list of posts

Configuring Local AWS Auth for VT SAML

Posted Aug 9, 2021 by Michael Irwin

If your AWS account is using VT SAML, it might be a little confusing on how to setup your local AWS config so the CLI works as expected. By the end of this post, you’ll be able to easily authenticate without thinking about it again.

The saml2aws Tool

There is a fantastic open-source tool called saml2aws that provides a lot of features, including keychain storage of username/password, automatic 2FA handling, role assumption, and more. After using experimenting with it, we found that we needed to make a few adjustments to get it working with our setup here at Virginia Tech. Therefore, we are maintaining our own fork on GitLab (this might eventually move out of the Common Platform project, so stay tuned about that). Specifically, our fork does the following:

  • Recognize and ignore interstitial pages. These include the verify recovery options, password expiration reminders, etc.
  • Adjust for slightly different URL paths. Since the URL patterns aren’t standardized, our implementation uses slightly different paths
  • Add support for the duo-mfa-option on the command line. This lets us complete the login without requiring user prompt. We’ve contributed this back to the upstream project in this pending pull request

Quick Prerequisites

The only prerequisite is to have your AWS account already configured to use VT SAML authentication and have a role that you can use. If you need help with this, check out this post to get VT SAML/AWS auth configured.

Getting Started

Fortunately, there isn’t too much to it!

  1. Download the latest version of the binary from the releases page. Pick the appropriate architecture for where you will be running.

  2. After downloading the appropriate artifact, rename it so it is simply named saml2aws.

  3. Make sure the binary is on your path. Doing this will vary depending on the OS you’re using. But, make sure that you can find it.

  4. Before plugging it into the AWS tooling, we need to authenticate. This will get our credentials stored in the keychain of our device, letting them be used by the tooling when no prompt/user input is allowed.

    saml2aws login --url=https://login.vt.edu --idp-provider=Shibboleth --mfa=Auto
    

    You should get prompted for the Duo auth and then be presented with all of the roles you can assume. Simply pick anyone of them, as the CLI (for whatever reason) doesn’t let you Ctrl+C out of it. 🤷‍♂️

  5. In your ~/.aws/config file, we’re going to create a config snippet that utilizes the credential_process feature. This config tells the AWS SDK to invoke the specified command, whose stdout must be a JSON object with the credentials the SDK should use. This gives a ton of flexibility. Use the snippet below, but replace the YOUR-ROLE-ARN with the ARN of your role and the name of the profile (sample-profile) with a name that makes sense for you.

    [profile sample-profile]
    region = us-east-1
    credential_process = saml2aws login --role=YOUR-ROLE-ARN --profile=sample-profile --skip-prompt --quiet --credential-process --url=https://login.vt.edu --idp-provider=Shibboleth --mfa=Auto --duo-mfa-option="Duo Push" --credentials-file=~/.aws/saml2aws-cache
    

    As a full working example, I might have something like this…

    [profile vt-platform-dvlp]
    region = us-east-1
    credential_process = saml2aws login --role=arn:aws:iam::123456789012:role/it.platform.account.aws.123456789012.admin --profile=vt-platform-dvlp --skip-prompt --quiet --credential-process --url=https://login.vt.edu --idp-provider=Shibboleth --mfa=Auto --duo-mfa-option="Duo Push" --credentials-file=~/.aws/saml2aws-cache
    

    Now, I know there’s a lot in that, but I’ll wait a moment to break down the various options and what’s going on.

  6. Now, run any AWS command and use that profile!

    # Specify the profile as an option on the CLI
    aws --profile=vt-platform-dvlp s3 ls
    
    # Or use environment variables
    export AWS_PROFILE=vt-platform-dvlp
    aws s3 ls
    

    You’ll get a Duo push to your default device and you’ll then get your result! If you run the command again, you shouldn’t get another push until your credentials expire.

And that’s it! What’s great is that this also works with more than just the AWS CLI, assuming your toolchain is using a relatively recent version of the AWS SDK. Check here for the supported SDKs and tools.

Explaining the Configuration

If you want to dive a little more into the configuration options being set, you’re in the right spot! Here are all of the flags being used (and why):

  • --role=ROLE_ARN - the role that will be assumed immediately after authenticating. Hopefully, this was pretty obvious!
  • --profile=PROFILE_NAME - saml2aws will store the credentials in a credentials file for future usage. This should match the AWS profile name so things work smoothly
  • --skip-prompt --quiet - don’t output any log info to stdout. If you’re troubleshooting and running the command on your own, feel free to remove these flags to get an idea of what’s going on
  • --credential-process - this tells saml2aws to output the credentials in the JSON format the AWS tooling is expecting
  • --url=https://login.vt.edu --idp-provider=Shibboleth --mfa=Auto - configuration on where the IdP is located and its provider. You should never have to change these
  • --duo-mfa-option="Duo Push" - the MFA option to use to validate the Duo login. If you don’t have a push device, you can also specify Phone Call. When running in an interactive mode, you can also use Passcode. There’s currently not a clean way to provide the passcode via the command line during the credential_process execution.
  • --credentials-file=~/.aws/saml2aws-cache - this is a quirky one. When AWS sees a credential file (normally at ~/.aws/credentials), that file and profile settings takes precedence and the tooling will not use the credential_process config. So, if saml2aws uses the same file AWS is, it will update the file and never get re-invoked. When the credentials expire, you’re stuck! By using another file, saml2aws can cache the credentials, but also handle expiration gracefully. Funky, but whatever…