AWS
Python SDK
SSO
Credentials
Cloud Computing

How to use the AWS Python SDK while connecting via SSO credentials

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

To use the AWS Python SDK (boto3) with SSO credentials, configure an SSO profile in ~/.aws/config, run aws sso login --profile your-profile to authenticate, then create a boto3 session with boto3.Session(profile_name='your-profile'). Boto3 automatically reads the cached SSO token and exchanges it for temporary AWS credentials. This avoids storing long-lived access keys and integrates with your organization's identity provider (Okta, Azure AD, etc.) through AWS IAM Identity Center (formerly AWS SSO).

Step 1: Configure the SSO Profile

ini
1# ~/.aws/config
2[profile dev-admin]
3sso_session = my-sso
4sso_account_id = 123456789012
5sso_role_name = AdministratorAccess
6region = us-east-1
7
8[sso-session my-sso]
9sso_start_url = https://my-company.awsapps.com/start
10sso_region = us-east-1
11sso_registration_scopes = sso:account:access

For the legacy (pre-session) format:

ini
1# Legacy format (still works)
2[profile dev-admin]
3sso_start_url = https://my-company.awsapps.com/start
4sso_region = us-east-1
5sso_account_id = 123456789012
6sso_role_name = AdministratorAccess
7region = us-east-1

Step 2: Log In via CLI

bash
1# Authenticate — opens browser for SSO login
2aws sso login --profile dev-admin
3
4# Verify credentials work
5aws sts get-caller-identity --profile dev-admin
6# {
7#   "Account": "123456789012",
8#   "Arn": "arn:aws:sts::123456789012:assumed-role/AdministratorAccess/[email protected]",
9#   "UserId": "AROA..."
10# }

Step 3: Use boto3 with the SSO Profile

python
1import boto3
2
3# Create a session with the SSO profile
4session = boto3.Session(profile_name='dev-admin')
5
6# Use any AWS service
7s3 = session.client('s3')
8buckets = s3.list_buckets()
9for bucket in buckets['Buckets']:
10    print(bucket['Name'])
11
12# EC2 example
13ec2 = session.client('ec2')
14instances = ec2.describe_instances()
15for reservation in instances['Reservations']:
16    for instance in reservation['Instances']:
17        print(f"{instance['InstanceId']}: {instance['State']['Name']}")

Using Environment Variables

bash
1# Set the profile via environment variable
2export AWS_PROFILE=dev-admin
3
4# Now boto3 uses it automatically without specifying profile_name
5python -c "import boto3; print(boto3.client('sts').get_caller_identity())"
python
1import os
2import boto3
3
4# Or set in Python
5os.environ['AWS_PROFILE'] = 'dev-admin'
6session = boto3.Session()  # Picks up AWS_PROFILE
7s3 = session.client('s3')

Multiple Accounts and Roles

ini
1# ~/.aws/config — multiple profiles for different accounts/roles
2[sso-session my-sso]
3sso_start_url = https://my-company.awsapps.com/start
4sso_region = us-east-1
5
6[profile dev-admin]
7sso_session = my-sso
8sso_account_id = 111111111111
9sso_role_name = AdministratorAccess
10region = us-east-1
11
12[profile staging-readonly]
13sso_session = my-sso
14sso_account_id = 222222222222
15sso_role_name = ReadOnlyAccess
16region = us-west-2
17
18[profile prod-deploy]
19sso_session = my-sso
20sso_account_id = 333333333333
21sso_role_name = DeployRole
22region = us-east-1
python
1import boto3
2
3# Switch between accounts/roles by profile
4dev_session = boto3.Session(profile_name='dev-admin')
5staging_session = boto3.Session(profile_name='staging-readonly')
6prod_session = boto3.Session(profile_name='prod-deploy')
7
8# Each session has its own credentials
9dev_s3 = dev_session.client('s3')
10staging_ec2 = staging_session.client('ec2')
11prod_lambda = prod_session.client('lambda')

Handling Token Expiration

python
1import boto3
2from botocore.exceptions import UnauthorizedSSOTokenError, TokenRetrievalError
3import subprocess
4import sys
5
6def get_session(profile_name='dev-admin'):
7    session = boto3.Session(profile_name=profile_name)
8
9    try:
10        # Test if credentials are valid
11        sts = session.client('sts')
12        sts.get_caller_identity()
13        return session
14    except (UnauthorizedSSOTokenError, TokenRetrievalError):
15        print("SSO token expired. Re-authenticating...")
16        subprocess.run(['aws', 'sso', 'login', '--profile', profile_name], check=True)
17        return boto3.Session(profile_name=profile_name)
18
19session = get_session()
20s3 = session.client('s3')
21print(s3.list_buckets()['Buckets'])

Programmatic SSO Token Refresh

python
1import boto3
2
3# Using the SSO OIDC client for programmatic login (headless environments)
4session = boto3.Session(region_name='us-east-1')
5sso_oidc = session.client('sso-oidc')
6
7# Register a client
8client_info = sso_oidc.register_client(
9    clientName='my-app',
10    clientType='public'
11)
12
13# Start device authorization
14auth_response = sso_oidc.start_device_authorization(
15    clientId=client_info['clientId'],
16    clientSecret=client_info['clientSecret'],
17    startUrl='https://my-company.awsapps.com/start'
18)
19
20print(f"Open this URL: {auth_response['verificationUriComplete']}")
21print(f"Enter code: {auth_response['userCode']}")
22
23# Poll for token (after user authorizes in browser)
24import time
25while True:
26    try:
27        token = sso_oidc.create_token(
28            clientId=client_info['clientId'],
29            clientSecret=client_info['clientSecret'],
30            grantType='urn:ietf:params:oauth:grant-type:device_code',
31            deviceCode=auth_response['deviceCode']
32        )
33        break
34    except sso_oidc.exceptions.AuthorizationPendingException:
35        time.sleep(auth_response['interval'])
36
37# Use the token to get role credentials
38sso = session.client('sso')
39credentials = sso.get_role_credentials(
40    roleName='AdministratorAccess',
41    accountId='123456789012',
42    accessToken=token['accessToken']
43)['roleCredentials']
44
45# Create a session with the temporary credentials
46authed_session = boto3.Session(
47    aws_access_key_id=credentials['accessKeyId'],
48    aws_secret_access_key=credentials['secretAccessKey'],
49    aws_session_token=credentials['sessionToken']
50)

Common Pitfalls

  • Forgetting to run aws sso login before using boto3: SSO credentials require an active login session. Without it, boto3 raises UnauthorizedSSOTokenError or TokenRetrievalError. Run aws sso login --profile your-profile and complete the browser authentication before running Python scripts.
  • SSO token expiration during long-running scripts: SSO tokens typically expire after 1-8 hours (configurable by the admin). Long-running scripts fail midway when the token expires. Wrap API calls in try-except for token errors and re-authenticate, or use sso_registration_scopes with longer session durations.
  • Using boto3.client() instead of boto3.Session().client(): boto3.client('s3') uses the default session, which may not pick up your SSO profile. Always create an explicit session: session = boto3.Session(profile_name='dev-admin') then session.client('s3').
  • Mixing SSO config formats (legacy vs session): The legacy format (all SSO fields in the profile) and the session format (sso_session reference) are not interchangeable. Mixing them in the same profile causes InvalidConfigError. Use one format consistently — the session format is recommended for token portability.
  • Running in CI/CD without interactive login: SSO login requires a browser. In CI/CD environments, use IAM roles (instance profiles, OIDC federation) instead of SSO, or use aws sso login with device authorization in a pre-step that caches the token for subsequent jobs.

Summary

  • Configure an SSO profile in ~/.aws/config with sso_start_url, sso_account_id, and sso_role_name
  • Run aws sso login --profile name to authenticate, then use boto3.Session(profile_name='name')
  • Handle token expiration with try-except and re-authentication for long-running scripts
  • Use multiple profiles in ~/.aws/config to switch between accounts and roles
  • Set AWS_PROFILE environment variable to avoid specifying profile_name in every session

Course illustration
Course illustration

All Rights Reserved.