AWS
Python SDK
SSO
Credentials
Cloud Computing

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

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

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

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.