Finally, SAML command line access for AWS STS.

At last, we have a solution for allowing Google’s Security Assertion Markup Language (SAML) based federation to use Amazon Web Services’ Security Token Service for authorization against AWS resources. This article is a followup to our previous write-up at When I Work Engineering on How to Setup Google SSO and AWS.

Today, I am pleased to announce the release of KeyMe by When I Work. KeyMe is a Python 2.7 library with a command line interface called fetch_creds. This library is available via pip as of today and the source is available for download over at our GitHub account . The code is an amalgamation of internal innovation, a lot of good old-fashioned experimentation and, of course, the incredible open source community. We would like to sincerely thank those who attempted this before us. Without those efforts and the results so kindly shared, this would have been a far more difficult journey.

Let’s get into how it works.

Previous solutions, while providing some useful functionality, ultimately fail to accommodate Google’s updated workflow. The ‘dance’ is now a 4 step process. Let’s break down each component:

  1. GET request to https://accounts.google.com/o/saml2/initsso?idpid=<idpid>&spid=<spid>&forceauthn=false
  2. POST request to <account_login_url> (gathered from step #1)
  3. POST request to <password_challenge_url> (gathered from step #2)
  4. POST request to <challenge_url> (gathered from step #3, if using MFA)

In step one, replace <idpid> and <spid> with the values for your Google SAML setup and your AWS SAML provider id. If you were to do this in your browser, you would be prompted for your username (e.g. johnny.appleseed@seeds.example). Once prompted, you would click continue and be directed to the password entry page. In Python, we can do this using the incredibly powerful beautifulsoup library. With beautifulsoup, we can then pull the account URL from the decoded HTML.

Next, we need to capture the password from the data payload. We will decode the HTML again, pull out the input fields and get the password URL.

If you have MFA devices enabled on your user, you would have one more HTML page to decode (to capture your PIN for Google’s 2FA).

If all went well, you will receive a SAML response from Google. We can now use this response with AWS’s Python boto3 library. Let’s verify that we are getting a SAML response:

Now that we know we have valid SAML from Google, we can pass that to boto3.

This will return the values we need to interact with AWS resources such as EC2, S3 and others.

How to use the `fetch_creds` command line tool.

fetch_creds allows a user to log in and ‘fetch’ their credentials. First, we need to generate a configuration file to store some options. The tool will walk you through the process of generating that file if you call fetch_creds init.

This call will walk you through some questions about your IDP, SP, AWS region, MFA status and username. You will need to get the principal and role ARNs from your AWS account or manager of your AWS accounts. This is a one-time process. Once completed, it will not need to be re-run. If you have more than one AWS account, you can run this command more than once with different names.

$ fetch_creds init
Please enter a name for this config: dev
Please enter your google idp id: ******
Please enter your aws sp id: *********
Which AWS Region do you want to be defualt?[us-east-1]:
Please provide your default principal ARN: arn:aws:iam::**********:saml-provider/GoogleAppsProvider
Please provide your default role arn: arn:aws:iam::***************:role/GoogleAppsDeveloper
Do you want to provide a default username? [y/N]: n
Do your want to enable MFA tokens? [y/N]: n

Next, finish the exercise with:

$ fetch_creds login

This command will return your temporary AWS access credentials as exportcommands. These credentials expire and, by default, are valid for one hour after creation (AWS STS has enforced limitations for temporary credentials, see here for more details). If you wish to retrieve credentials in a different region, you can use the --region flag, like so:

$ fetch_creds login --region us-west-2

Basic Usage

As KeyMe is available via pip, you can use this anywhere you can execute a pip install keyme. Once you have it installed, it’s just a matter of putting this at the top of your Python scripts.

from keyme import KeyMe

Then, you can use it just like any other Python class.

Like what you read? Give Richard Genthner a round of applause.

From a quick cheer to a standing ovation, clap to show how much you enjoyed this story.