Boto3 Assume Cross Account Role with MFA

Viewed 1117

Using python3 and boto3 how can I assume a role in a different AWS account that requires Multi-Factor-Authentication (MFA) to be enabled when assuming the role?

Looking for a code example. Similar questions on this site cover technology other than boto3 or do not include the MFA requirement.

1 Answers

Using boto3 you need to allow the user to input the MFA token just before switching role. The code below shows an example of switching to a role to list buckets in a different account. The important point is adding the SerialNumber and the TokenCode options to the sts_client.assume_role() call.

The returned credentials can then be used with another boto3 client to do some actual work, in this case list s3 buckets in the target account.

#!/usr/bin/env python
import boto3

sts_client = boto3.client('sts')

def assume_role_with_mfa(role_arn):

    '''
        Assume cross account role with MFA and return credentials
    '''

    mfa_otp = input("Enter the MFA code: ")

    assumedRoleObject = sts_client.assume_role(
        RoleArn=role_arn,
        RoleSessionName='mysession',
        SerialNumber="arn:aws:iam::987654321098:mfa/my_userid",
        DurationSeconds=3600,
        TokenCode=mfa_otp
    )

    # From the response that contains the assumed role, get the temporary
    # credentials that can be used to make subsequent API calls
    return assumedRoleObject['Credentials']


# Get the cross-account credentials, then use them to create 
# an S3 Client and list buckets in the account

creds = assume_role_with_mfa("arn:aws:iam::123456789012:role/myrole")

s3_client = boto3.client(service_name="s3",
            aws_access_key_id=creds['AccessKeyId'],
            aws_secret_access_key=creds['SecretAccessKey'],
            aws_session_token=creds['SessionToken'])
        
buckets = s3_client.list_buckets()
for bucket in buckets['Buckets']:
    print(bucket['Name'])

I hope this is a useful for reference for future searchers.

Related