How to Retrieve AWS Short-term Credentials when Authenticating through Federated IDPs

The AWS CLI subcommand assume-role-with-saml can be utilised to retrieve temporary credentials when accessing SAML2-based Identity Provider (IDP) that has been federated to AWS. Several third party login “helpers” are available for this purpose, for example, aws-google-auth can be used when Google is the federated IDP. However, these tools are not always updated to reflect authentication flow changes implemented by the IDP or other package dependencies. For this reason, understanding how to source credentials with assume-role-with-saml is the fallback option when all else fails.

This article provides an end-to-end walk-through on working with — assume-role-with-saml.

Examples used throughout assume Google as being the federated IDP.

Before continuing, some recommended background reading on SAML-enabled authentication flow can be found in the official documentation.

Steps to Retrieve STS Credentials (TL;DR)

The high level summary of steps involved are listed below. Subsequent sections provide further details on each step.

  1. Authenticate with federated account via IDP and access the AWS console by following the redirect URL
  2. Once the AWS console loads, use the web browser’ Dev Tools to locate values for the following:
    🔹SAML assertion
    If the following are already known, then move on to the next step
    🔹ARN of the role to assume
    🔹ARN of the IDP
  3. Using aws sts assume-role-with-saml with values obtained from Step (2) above, generate short-term credentials
  4. Use aws configure to create a profile for storing the credentials, or export as environment variables
  5. Refresh expired credentials by repeating the process with a new/refreshed SAML assertion

1. Authenticate Through IDP

The first step in the process is to authenticate through the IDP’ portal. For example, an organisation may have federated to AWS using domain somecompany.com through Google workspace and provisioned user john.smith@somecompany.com with the appropriate AWS roles.

Once successfully signed in, the user clicks on redirect URL (from Google Apps) to access the AWS console. During this process, the IDP sends a SAML Assertion to the AWS authentication endpoint.

2. Retrieve SAML Assertion, role and saml-provider Arns

SAML Assertion

When the AWS endpoint successfully verifies the SAML assertion, the web browser (client) loads the console, along with a list of authorised roles to select/assume. At this point, the SAML response/assertion can be retrieved from cache by using the Dev Tools for the respective web browser.

Alternatively, browser extensions are available to assist in viewing the SAML response.

Not all web browser extensions are maintained/updated regularly to accommodate for browser and/or SDK updates. For this reason, understanding how to retrieve the assertion with the Dev Tools is ideal.

  • To view the SAML assertion, search the Elements panel for samlresponse and note down the corresponding value (the assertion is base64 encoded)
  • Portion of a sample SAML Assertion from the above image:

SAML Response: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz...

  • Save the SAML response to a file (exclude leading/trailing double quotes)

file: /home/<user>/saml-assert.txt

PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz....
  • If the IDP and role ARNs are known, skip to section (3).

Role Arn

  • To obtain the ARN of the role to be assumed, right click on the role name and Inspect the element details
  • The following example shows the ARN corresponding for the Administrator role
  • Note down the role ARN arn:aws:iam:nnnnnnnnnnnn:role/Administrator

Identity Provider ARN

  • To locate the IDP ARN, decode the base64 encoded SAML assertion and search the output for string saml-provider.
$ cat /home/<user>/saml-assertion.txt | \
base64 --decode | \
xmllint --format - | \
grep "saml-provider"
  • Note down the ARN of the saml-provider, which takes the format
arn:aws:iam::nnnnnnnnnnnn:saml-provider/xxxxxxxx.....

3. Retrieve Credentials with assume-role-with-saml

The three key values required as inputs toassume-role-with-saml are listed below

$ aws sts assume-role-with-saml \
--principal-arn <value> \
--role-arn <value> \
--saml-assertion <value> or file://path

🔹--principal-arn: ARN of the IDP

🔹--role-arn : ARN of the role to be assumed

🔹--saml-assertion: the raw SAML assertion, or the path to a file containing the assertion

Substituting the values noted in the previous examples, retrieve short-term credentials for the Administrator role by running:

$ aws sts assume-role-with-saml \
--principal-arn arn:aws:iam::nnnnnnnnnnnn:saml- provider/xxxxxxxx..... \
--role-arn arn:aws:iam::nnnnnnnnnnnn:role/Administrator \
--saml-assertion file:///home/<user>/saml-assert.txt
  • This should return output similiar to the following:
{
"Credentials": {
"AccessKeyId": "A*********************",
"SecretAccessKey": "s*******************",
"SessionToken": "T***********=",
"Expiration": "2022-10-13T05:30:00+00:00"
},
...
...
..
}
  • To start using the credentials, create a profile using aws configure or set/export the appropriate environment variables

Note: assume-role-with-saml must be executed within 5 minutes from the time AWS verifies the SAML assertion and issues a token, otherwise the following error is generated:

An error occurred (ExpiredTokenException) when calling the AssumeRoleWithSAML operation: Token must be redeemed within 5 minutes of issuance

4. Using the Credentials with AWS CLI

Option 1: Create CLI Profile to Store Credentials

  • Use aws configure to create a profile to store the credentials
  • In the following example, a profile named assumed_admin is created to store the credentials for the Administrator role:
$ aws configure set region us-east-1 --profile assumed_admin$ aws configure set aws_access_key_id A********************* --profile assumed_admin$ aws configure set aws_secret_access_key s******************* --profile assumed_admin$ aws configure set aws_session_token T***********= --profile assumed_admin$ aws configure set aws_session_expiration 2022-10-13T05:30:00+00:00 --profile assumed_admin
  • Verify the profile identity
$ aws --profile assumed_admin sts get-caller-identity
  • Output should include the correct role
{
"UserId": "***************:******@******.com",
"Account": "nnnnnnnnnnnn",
**"Arn": "arn:aws:sts::nnnnnnnnnnnn:assumed-role/Administrator/*****@**************.com"**
}
  • Start using the profile with the CLI
$ aws --profile assumed_admin <command> <subcommand>

Option 2: Export/Set Environment Variables

  • To use environment variables instead profiles, export the credentials:
$ export AWS_ACCESS_KEY_ID=A*********************
$ export AWS_SECRET_ACCESS_KEY=s*******************
$ export AWS_SESSION_TOKEN=T***********=
  • Verify identity
{
"UserId": "***************:******@******.com",
"Account": "nnnnnnnnnnnn",
"Arn": "arn:aws:sts::nnnnnnnnnnnn:assumed-role/Administrator/*****@**************.com"
}
  • Start using the CLI
aws <command> <subcommand>

5. Refresh Expired Credentials

Once credentials expire, they can be refreshed by rerunning assume-role-with-saml using a new SAML assertion.

To retrieve a new assertion, close the AWS console web browser tab/page and reopen a new console session by clicking on the redirect URL. Repeat the tasks outlined in section (2) to retrieve the assertion.

Writing a Custom Helper Script to Save Credentials to CLI config/credentials

Building a fully automated solution to perform the actions discussed would not be trivial . The fact that not all IDPs have identical authentication portals makes full automation impractical. However, semi-automation would be plausible.

A sample of a semi-automated bash script to add/refresh credentials for a CLI profile is shown below.

  • The script requires manual intervention to locate and save the SAML assertion.
  • If the SAML IDP and/or role ARNs are not known, then they will need to be manually located

Sample Script

Script name: refresh_sts_creds.sh

Source code:

Usage

  • Save the script locally and add execute permission.
chmod u+x refresh_sts_creds.sh
  • Install JSON parser jq
sudo apt install jq
  • Ensure the SAML assertion has been saved to a file as outlined in section (2).
    🔹for example: /home/<user>/saml-assertion.txt
  • Run the script by supplying the following parameters
    🔹Parameter 1: Profile name in credentials/config to store short-term credentials
    🔹Parameter 2: Principal/saml-provider ARN
    🔹Parameter 3: ARN of role to be assumed
    🔹Parameter 4: Path to file containing the SAML assertion

Assuming the following sample values :

🔹credentials/config profile name: assumed_admin
🔹principal/saml-provider ARN:
arn:aws:iam::nnnnnnnnnnnn:saml-provider/xxxxxxxx
🔹ARN of role to be assumed: arn:aws:iam::nnnnnnnnnnnn:role/Administrator
🔹Path to file containing the SAML assertion: /home/<user>/saml-assertion.txt

run the script as follows:

$ ./refresh_sts_creds.sh \
assumed_admin \
arn:aws:iam::nnnnnnnnnnnn:saml-provider/xxxxxxxx \
arn:aws:iam::nnnnnnnnnnnn:role/Administrator \
/home/<user>/saml-assert.txt

Check the ~/.aws/credentials & ~/.aws/config files to ensure the corresponding profile contains the correct credentials.

--

--

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