Use Boto3 to Assume a Role in another AWS Account

AWS allows you to assume roles in other AWS accounts. Its a nice feature that allows you to log into 1 account, assume a role in another account, and issue API commands as if you had signed into the 2nd account. You can have all users sign into 1 central account, then assume roles into other accounts based on a job role. Using the AWS gui, this is a few mouse clicks, but here I’ll show you how to assume a role using BOTO3.

import boto3

# Create session using your current creds
boto_sts=boto3.client('sts')

# Request to assume the role like this, the ARN is the Role's ARN from 
# the other account you wish to assume. Not your current ARN.
stsresponse = boto_sts.assume_role(
    RoleArn="OtherAccountARNGoesHere",
    RoleSessionName='newsession'
)

# Save the details from assumed role into vars
newsession_id = stsresponse["Credentials"]["AccessKeyId"]
newsession_key = stsresponse["Credentials"]["SecretAccessKey"]
newsession_token = stsresponse["Credentials"]["SessionToken"]

# Use the assumed session vars to create a new boto3 client with the assumed role creds
# Here I create an s3 client using the assumed creds.
s3_assumed_client = boto3.client(
    's3',
    region_name='us-east-1',
    aws_access_key_id=newsession_id,
    aws_secret_access_key=newsession_key,
    aws_session_token=newsession_token
)

# Here I create an s3 resource with the assumed creds
s3_assumed_resource = boto3.resource(
    's3',
    region_name='us-east-1',
    aws_access_key_id=newsession_id,
    aws_secret_access_key=newsession_key,
    aws_session_token=newsession_token
)

# Now we can use s3_assumed session for calls using the assumed role.
# As in this example where I list buckets using the assumed creds
response = s3_assumed_client.list_buckets()

# Or like this use of the resource to create a bucket object.
mybucket = s3_assumed_resource.Bucket('OtherAccountBucket')

That’s it. Happy coding.

Tagged , , , . Bookmark the permalink.

8 Responses to Use Boto3 to Assume a Role in another AWS Account

  1. Alfredo says:

    There is a minor typo on line 8:

    stsresponse = boto_sts_assume_role

    it should be:

    stsresponse = boto_sts.assume_role

  2. Meg says:

    Hi,
    I am new to aws and python. Apologise for if this sound basic question.

    Can you please elaborate on how to Save the details from assumed role into vars. I used above code, entered assume role arns, region and bucket name. When i run the code i am getting Access denied message.

    I feel i am missing on providing some key information but unable to figure it out. Can you please help me.

    Thanks,
    Meg

    • mike says:

      Depends on the error and what is throwing it. Your Access Denied could be related to trying to assume the role. Maybe your creds don’t allow you to assume a role. Make sure that you can do this in the GUI to eliminate any AWS config errors first.

  3. Tom says:

    I am getting the following error
    botocore.exceptions.ClientError: An error occurred (InvalidClientTokenId) when calling the AssumeRole operation: The security token included in the request is invalid
    However when I use aws commands via the cli, i can assume a role and list out the buckets.

    • mike says:

      It works in my test here… Would you send me the code and full error message (minus your creds of course). I’d like to see whats up. It wouldn’t be the first time AWS changed things on the backend.

  4. Ana says:

    can yoiu post how to use s3_assumed_client as this giving me error An error occurred (AccessDenied) when calling the GetObject operation: Access Denied

    • mike says:

      The code in the example is how to assume the role only. IF you are getting an access denied when trying to use the assumed_client then perhaps the assumed client role lacks the permissions needed in the other account. The role in the target account must have the correct permissions to do an s3:GetObject on a bucket.

Leave a Reply

Your email address will not be published. Required fields are marked *

Solve : *
30 − 11 =