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.
- Authenticate with federated account via IDP and access the AWS console by following the redirect URL
- 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 - Using
aws sts assume-role-with-saml
with values obtained from Step (2) above, generate short-term credentials - Use
aws configure
to create a profile for storing the credentials, or export as environment variables - 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 forsamlresponse
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 theAdministrator
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.