AWS STS Credentials and Google Apps Federated User

This write-up outlines methods of working with the AWS Secure Token Service (STS) and Federated user accounts, where Google has been established as the Identity Provider. It is based on a recent experience where AWS programmatic access was only permitted via STS temp credentials.

A summary of the scenario and what we aim to achieve are as follows:

  • You are a developer working with the aws cli for the purposes of testing your Dev stack.
  • Your organisation has enabled SSO via SAML, with Google as the Identity Provider.
  • Your Google account (eg@myexample.com) has been provisioned for access to AWS.
  • Access to AWS resources requires that you authenticate using your Federated user and request temporary credentials using the Secure Token Service (STS). You are advised that the role you need to “assume” to request the credentials is, arn:aws:iam::111222333444:role/saml-init.
  • Once you have your STS temp credentials, you will then be permitted to “assume” a secondary development role, which has been provisioned to allow access to AWS resources such as S3 and Elastic Container Registry (ECR). The arn of the secondary role is arn:aws:iam::888777666555:role/assumed-dev

Federated Login Helper (aws-google-auth)

aws-google-auth is an authentication helper Python package, offered by CEVO (Docker also available at git repo). It is invoked via command line using docker and can be used to generate STS credentials using your Federated Google account. The package can also be installed locally to your existing Python environment, or via building the docker.

Option 1: Local Python Installation

If you prefer to use the your local Python installation, then install aws-google-auth via pip:

$ pip install aws-google-auth

Option 2: Docker Installation

Clone CEVO git repo,

$ git clone https://github.com/cevoaustralia/aws-google-auth \
aws-google-auth

and build the image using:

$ cd aws-google-auth
$ docker build --rm -t aws-google-auth .

The docker image is used for the examples throughout the article.

Locating Google Identity and SAML Provider IDs (IDPID/SPID)

Before being able to use the image, you will need to know the following details:

  • Google Identity Provider ID (idpid)
  • SAML Service Provider ID assigned by Google (spid)

Your AWS System admins should provide these details. If they are not provided, then you should be able to find these through the Google App AWS link address details.

From your web browser, go to Google Apps launcher. Scroll until you see the AWS Google App….hover your mouse over the icon to view the link address details in your browser’s status bar. Alternatively you can right click on the icon and copy/paste the link address into Notepad.

Make a note of your idpid and spid. They are required as parameter inputs to aws-google-auth.

Generate STS Temporary Credentials

The aws-google-auth helper stores/adds authentication data to $HOME/.aws/config and $HOME/.aws/credentials files so it's important that the storage hosting these files is encrypted at rest.

The Docker can be run with a host:container mount $HOME/.aws:/root/.aws. This will allow direct access to files $HOME/.aws/config & $HOME/.aws/credentials. Alternatively, you can setup an alternate host location and have the container generate config/credentials into this location.

To directly edit your default credentials/config files, then specify the following mount option in your docker command:

  • Linux-based hosts -v $HOME/.aws:/root/.aws
  • Windows host -v c:/Users/<username>/.aws:/root/.aws

Run the Docker Image

To get a full list of command line options for aws-google-auth, run the docker with -h option.

For the examples in the article, the following options are used,

$ docker run -it aws-google-auth -h
..
...
-u USERNAME (Google Apps username)
-I IDPID (Google Identity Provider identifier)
-S SPID (SAML Provider identifier )
-R REGION (AWS region endpoint)
-d DURATION (Credential duration in SECONDS)
-p PROFILE (AWS profile - defaults to value of $AWS_PROFILE)
-r ROLE_ARN (The ARN of the role to assume. If not supplied
,a list roles to choose from will be listed)
..
...

with the following sample values,

username=eg@myexample.com
idpid=X7x0Xxxx
spid=000111000111
region=us-east-1
duration=3600
profile=sts-temp
role_arn=arn:aws:iam::111222333444:role/saml-init

Using these values, we generate STS temporary credentials as follows:

$ docker run -it -v $HOME/.aws:/root/.aws aws-google-auth \
-u eg@myexample.com \
-I X7x0Xxxx \
-S 000111000111 \
-R us-east-1 \
-d 3600 \
-p sts-temp \
-r arn:aws:iam::111222333444:role/saml-init

For MFA with SMS verification enabled, you will be required to enter your Google password and respond with the SMS code.

Google Password: *******
Enter SMS token: G-nnnnnn

After authentication is complete, the expiration time for temporary credentials should be displayed

Assuming arn:aws:iam::111222333444:role/saml-init
Credentials Expiration: 2020-07-12 00:41:15+00:00

The AWS profile, sts-temp (-p sts-temp) should now contain the STS temporary credentials.

Verify AWS Config & Credentials

The credentials and config files can be checked to ensure profile sts-temp has been updated/generated with valid entries.

$HOME/.aws/config

[profile sts-temp]
region = us-east-1
google_config.ask_role = False
google_config.keyring = False
google_config.duration = 3600
google_config.google_idp_id = X7x0Xxxx
google_config.role_arn = arn:aws:iam::111222333444:role/saml-init
google_config.google_sp_id = 000111000111
google_config.u2f_disabled = False
google_config.google_username = eg@myexample.com
google_config.bg_response = None

$HOME/.aws/credentials

[sts-temp]
aws_access_key_id = exampleAAAAAAAAAAAAAAAAAAAAAA
aws_secret_access_key = exampleBBBBBBBBBBBBBBBBBBBBB
aws_security_token = exampleCCCCCCCCCCCCCCCCCC
aws_session_expiration = exampleDDDDDDDDDDDDDDDDDDDDDD
aws_session_token = exampleEEEEEEEEEEEEEEEEEEEE

Refreshing AWS STS Credentials

To refresh/update STS credentials for the same profile is only a matter of running the docker command again, supplying the same profile name
(-p sts-temp).

Switch to/Assume Secondary Role using STS Credentials

As mentioned earlier on, to perform Dev activities, we need to assume/switch to secondary role arn:aws:iam::888777666555:role/assumed-dev using the STS temporary credentials.

This secondary role has been provisioned with access to an Elastic Container Registry (ECR) and S3. To use the temporary STS credentials with this role, we need to create a new AWS profile, specifying the role_arn.

The following examples show the AWS profile being created with name dev-env for our secondary role.

$HOME/.aws/config

[profile dev-env]
region = us-east-1
source_profile = sts-temp
role_arn = arn:aws:iam::888777666555:role/assumed-dev

If you prefer, you can use the aws configure command to setup the new AWS profile.

$ aws configure set profile.dev-env.region us-east-1
$ aws configure set profile.dev-env.source_profile sts-temp
$ aws configure \
set profile.dev-env.role_arn \ arn:aws:iam::888777666555:role/assumed-dev

When the profile above is specified in AWS CLI commands (--profile dev-env), the secondary role (arn:aws:iam::888777666555:role/assumed-dev) is "assumed" with the STS temporary credentials being sourced from section [sts-temp] in $HOME/.aws/credentials.

Putting it all Together

The following is a re-cap of the process.

1. Authenticate with Federated User and Retrieve STS Credentials

  • Authenticate with Federated Google account using aws-google-auth and obtain STS temporary credentials for profile sts-temp.
$ docker run -it -v $HOME/.aws:/root/.aws aws-google-auth \
-u eg@myexample.com \
-I X7x0Xxxx \
-S 000111000111 \
-R us-east-1 \
-d 3600 \
-p sts-temp \
-r arn:aws:iam::111222333444:role/saml-init

2. Configure New AWS Profile for Secondary Role to use STS

  • Create new AWS profile for the secondary role

The below shows the setup required for profile dev-env

$HOME/.aws/config

[profile dev-env]
region = us-east-1
source_profile = sts-temp
role_arn = arn:aws:iam::888777666555:role/assumed-dev

or, alternatively, add the profile to $HOME/.aws/config via aws configure.

$ aws configure set profile.dev-env.region us-east-1
$ aws configure set profile.dev-env.source_profile sts-temp
$ aws configure set profile.dev-env.role_arn \ arn:aws:iam::888777666555:role/assumed-dev

3. Start Using CLI Commands

The examples that follow show commands which will transparently “assume” the secondary role arn:aws:iam::888777666555:role/assumed-dev.

  • S3 list bucket subdir/key
$ aws s3 ls s3://mybucket/mydir --profile dev-env
  • ECR get docker registry login, get-login
$ aws ecr get-login --registry-ids xxxxxxxxxxxx --no-include-email --profile dev-env

4. Update/Refresh Expired STS credentials

Once the STS temporary credentials have expired, re-execute aws-google-auth to refresh,

$ docker run -it -v $HOME/.aws:/root/.aws aws-google-auth \
-u eg@myexample.com \
-I X7x0Xxxx \
-S 000111000111 \
-R us-east-1 \
-d 3600 \
-p sts-temp \
-r arn:aws:iam::111222333444:role/saml-init

and continue using the profile for the secondary role.

Programmatic Access with Python & boto

The below sample Python code shows the secondary role being “assumed” by specifying profile dev-env. Authentication happens transparently due to the configuration performed earlier on for this profile.

import boto3

session = boto3.Session(profile_name='dev-env')
dev_s3_client = session.client('s3')

for key in dev_s3_client.list_objects(Bucket='mybucket')['Contents']:
print(key['Key'])

Final Comments

Some of the benefits of enabling Federated logins with temporary credentials are as follow:

  • Removing the user’s account from the linked Identity Provider/Organisation (eg. Google GSuite) ensures the user no longer has access to the AWS account.
  • The use of temporary credentials with a short expiration period (as opposed to issuing non-expiring keys), enforces the concept of key rotation.
  • Managing comprised temporary credentials is likely to be simpler than managing comprised permanent keys.

Learner. Interests include Cloud and Devops technologies.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store