The Rhythmic Blog
IAM Access Keys bad. AWS SSO good.
IAM Access Keys are evil, permanent in nature, and bypass security controls like MFA and session timeout once issued. Often, IAM User-based access keys are not part of the employee offboarding process, making them even more dangerously durable. Essentially, IAM Acces Keys act as a sort of always-on VPN client between a device (e.g., an engineer’s laptop) and an AWS account. And when created by developers, they tend to have very generous permissions.
Temporary credentials issued through AWS STS avoid this problem but have historically been clunky and frustrating working into a typical engineer experience. AWS IAM Identity Center (nee AWS SSO) has supported fetching temporary keys on your behalf since 2020 via the aws configure sso
and aws sso login
commandlets. However, it had a lot of rough edges and many continued to use other tools like aws-vault. As with most AWS features, it quietly got better over time.
The bottom line, the AWS IAM Identity Center gives you everything you need to securely authenticate to all of your AWS accounts, including CLI access. No long-lived credentials are used, and terminated users lose both console and CLI access within configurable session lifetimes. Third-party tooling is only necessary for eclectic use cases and in most cases will provide a less robust experience. And, setting up the CLI is simple.
This walkthrough assumes that your AWS account (or Organization) is already configured for AWS IAM Identity Center and that you have a somewhat new AWS CLI v2 client configured (2.4 or newer should be fine).
Configuring the CLI
To get started, you’ll need to know your SSO Start URL and SSO Region. If you log in from your Identity Provider (e.g., Okta), just sign in as normal to get started. Pick the account you are configuring the CLI for and click “Command line or programmatic access”. The resulting screen will give you the URL and Region.
If you don’t know your SSO URL already, picking the Command line or programmatic access from any account in the org is a convenient way to get it.
Once you have these in hand, you can run aws sso configure
and follow the guided prompts to set your configuration. You’ll be prompted for a few fields before being sent on a browser auth flow. That will look roughly like this:
$ → aws configure sso SSO session name (Recommended): sampleco SSO start URL [None]: https://d-90676378d1.awsapps.com/start# SSO region [None]: us-east-1 SSO registration scopes [sso:account:access]: Attempting to automatically open the SSO authorization page in your default browser. If the browser does not open or you wish to use a different device to authorize this request, open the following URL: https://device.sso.us-east-1.amazonaws.com/ Then enter the code: ZLVV-GPSK
Some considerations for these fields:
- Session Name: this is for your own needs only and corresponds to all accounts available to you from the SSO landing page, typically your company.
- SSO registration scopes: you typically want to leave this as
sso:account:access
, and that is all that is required for the AWS CLI itself.
Once you have completed the fields above, you are redirected to the SSO login flow. If you can’t use a browser from the device you’re on, you can use the specified URL and code to use an alternative flow on a device that supports a web browser. In the browser-based flow you are presented with the same code and asked to approve:
Click Confirm and continue to confirm you initiated the request, you will have an explicit second request to authorize access. This is a bit misleading, as you are not granting the AWS CLI any additional access beyond what you already have. So, click Allow.
Return to your terminal to complete the configuration process:
There are 10 AWS accounts available to you. Using the account ID 680023020963 The only role available to you is: AdministratorAccess Using the role name "AdministratorAccess" CLI default client Region [None]: us-east-1 CLI default output format [None]: text CLI profile name [AdministratorAccess-680023020963]: sampleco-sandbox-admin To use this profile, specify the profile name using --profile, as shown: aws s3 ls --profile sampleco-sandbox-admin
Note that you are prompted to select an account and then select a role that you have access to (as defined in AWS IAM Identity Center). The CLI profile name will be how you determine which AWS Organization, AWS Account, and IAM Role you wish to access, so it is recommended that the name include all three.
You are set now. As long as you have an active session to AWS SSO, your access to AWS via the CLI will work seamlessly. To make life easier, you can set AWS_PROFILE to avoid typing --profile sampleco-sandbox-admin
constantly.
$ export AWS_PROFILE=sampleco-sandbox-admin [AWS:sampleco-sandbox-admin] $ aws sts get-caller-identity 680023020963 arn:aws:sts::680023020963:assumed-role/AWSReservedSSO_AdministratorAccess_30af48c2f49cd1ce/e@x.com AROAZ4VEH2WRWTELJISXI:e@x.com
With AWS_PROFILE set, any modern scripts or SDKs you might invoke will automatically find the correct credential source without any further action on your part. It just works, as you would expect.
Refreshing Tokens
When you use AWS SSO, tokens are fetched and refreshed automatically by the CLI on your behalf. As a result, in most circumstances, you can expect to use the AWS CLI seamlessly for the duration of your AWS SSO session. The length of the session is determined by either the Maximum session duration setting in AWS IAM Identity Center (default 8 hours) or the maximum session duration specified by your IdP (e.g., Entra ID/ADFS, Okta). IdPs often do not specify a maximum or use 12 or 24 hours.
This is beneficial for long-running processes. Third-party tools like aws-vault use the credential process, which requests AWS credentials via a programmatic method at the beginning of a process. Thus even though aws-vault supports refreshing tokens, it can only do so per process. Thus, a long-running script or a client using the SDK may fail if the STS token expires before a subsequent AWS API call.
Because AWS SSO is natively embedded in the CLI and most SDKs, this is less likely to occur. There are some situations in which a process may fail due to an expired STS token, but in general, this proves to be far more reliable than using the credential process to refresh tokens on your behalf.
Juggling Profiles and Other Configs
The above process configures a single account/role and needs to be repeated for every combination you need to use. In addition, you may have other accounts or profiles configured for AWS CLI access. Juggling these can waste time, and many teams invest in automation to build out a default AWS configuration for everyone to use. The example above produced the following changes to ~/.aws/config
:
[profile sampleco-sandbox-admin] sso_session = sampleco sso_account_id = 680023020963 sso_role_name = AdministratorAccess region = us-east-1 output = text [sso-session sampleco] sso_start_url = https://sampleco.awsapps.com/start# sso_region = us-east-1 sso_registration_scopes = sso:account:access
Generating this is easily automated and requires basic knowledge of the environment–the SSO URL/region, account ID(s), and role name(s). With an appropriately built config file, you can quickly switch between hundreds of accounts across AWS Organizations if needed.
Of course, it can get confusing to remember all of the account/role combos, so a good naming strategy and the aws configure list-profiles
command are your friends.
All of this co-exists perfectly well with any other AWS access methods, including conventional access methods like fixed IAM Access Keys. You can use AWS profiles backed by AWS SSO in parallel with your existing methods while you validate that everything works as expected.
Long Running Processes
While AWS SSO makes using temporary tokens seamless and often easier than IAM Access Keys, some processes may prove resistant to automatic token refresh. This is especially true of older SDKs or languages.
It may also be the case that a process needs to run longer than the maximum session length an organization will allow. Many organizations require access to be cut off within 24 hours of termination of an employee. This post is based on running processes in the context of a user, and so there is no workaround to refreshing tokens beyond the maximum session of a user.
The best practice is to run such processes in the context of a service account. This can slow progress when doing data analytics, machine learning, and similar environments. In such cases, it can be beneficial to rely on remoting tools like VS Code Remote, which can invoke long-running processes on EC2 instances or ECS tasks with more durable permissions. In many cases, making such an adjustment often requires surprisingly little upfront change and creates an impact in other, unexpected areas.