Reputation: 789
I found an example for boto + MFA:
http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_mfa_sample-code.html
But I cannot find an example of how to do it with boto3. Any equivalent boto3 examples?
Thanks!
Upvotes: 9
Views: 14724
Reputation: 233
Trying to understand better how to use Session in different cases, I've written the following example:
Considering the Config and Credentials files are set under ~.aws/config.
Config file looks similar to the following:
[profile mfa] mfa_serial = arn:aws:iam::ACCOUNT_ID:mfa/MFA_DEVICE_NAME region=us-east-1 [profile non-mfa] region=us-east-1
the python file:
import os
import boto3
from botocore.session import Session
def get_profile_name():
profile_name = input(
"Which AWS account do you want to use to connect to? \n "
"Choose Profile: \n0. default profile\n1. profile with mfa\n2. profile without mfa\n"
"Please enter either 0 or 1 or 2: ")
return profile_name
def init_aws_session():
profiles = Session().available_profiles # profiles = {0: 'default', 1: 'mfa', 2: 'non-mfa'}
profile_name = get_profile_name()
if profile_name == "1":
# profile with mfa
# get the mfa device
mfa_serial = Session().get_scoped_config().get('mfa_serial')
sts = boto3.client('sts')
# get mfa code from user
mfa_code = input("Enter the MFA code: ")
mfa_token = sts.get_session_token(
SerialNumber=mfa_serial,
TokenCode=mfa_code
)
profile_session = boto3.Session(profile_name=profiles[int(profile_name)],
aws_session_token=mfa_token["Credentials"]["SessionToken"],
aws_secret_access_key=mfa_token["Credentials"]["SecretAccessKey"],
aws_access_key_id=mfa_token["Credentials"]["AccessKeyId"]
)
return profile_session
elif profile_name == "2":
# profile without mfa
profile_session = boto3.Session(profile_name=profiles[int(profile_name)])
credentials = profile_session.get_credentials().get_frozen_credentials()
profile_session = boto3.Session(profile_name=profiles[int(profile_name)],
aws_access_key_id=credentials.access_key,
aws_secret_access_key=credentials.secret_key)
profile_session.get_credentials()
return profile_session
elif profile_name == "0":
# default profile
# act according to your needs
pass
else:
print("Not valid option entered")
if __name__ == "__main__":
# get session
session = init_aws_session()
# Use the session to create a client
ec2 = session.client("ec2", region_name='us-east-1',
verify=os.getenv("CA_BUNDLE"))
# get instances using client
resources = ec2.describe_instances()
print(resources)
# Use the session to create a resource
instance_id = 'i-012345678901'
ec2 = session.resource('ec2')
instance = ec2.Instance(instance_id)
print(instance)
Another nice article with code example for MFA only: medium.com/Charles Victus
Upvotes: 0
Reputation: 887
A simple example of creating Virtual MFA and assigning it to a user:
import pyotp as pyotp
from datetime import datetime, timedelta
iam = boto3.client("iam")
user = iam.create_user(user_name="some_user_name")
mfa = iam.create_virtual_mfa_device(virtual_mfa_device_name="some_virtual_mfa_name")
totp = pyotp.TOTP(mfa['VirtualMFADevice']['Base32StringSeed'])
code_1 = totp.generate_otp(totp.timecode(datetime.now() - timedelta(seconds=30)))
code_2 = totp.generate_otp(totp.timecode(datetime.now()))
iam.enable_mfa_device(
user_name=user["UserName"],
serial_number=mfa["SerialNumber"],
authentication_code1=code_1,
authentication_code2=code_2,
)
Upvotes: 1
Reputation: 85
The code below works but you have to use ~/.boto file with the correct credentials. SerialNumber is your MFA device serial or the full AWS ARN of it
#!/usr/bin/env python
import boto3
mfa_TOTP = input("Enter the MFA code: ")
client=boto3.client('sts')
response = client.assume_role(
RoleArn='arn:aws:iam::123456789:role/admin_full',
RoleSessionName='mysession',
DurationSeconds=3600,
SerialNumber='arn:aws:iam::987654321:mfa/myaccount',
TokenCode=mfa_TOTP,
)
Upvotes: 9
Reputation: 3941
In addition to answers by Zoltan, and Fauxsys, this could be another way to create AWS client
import boto3
mfa_otp = raw_input("Enter the MFA code: ")
client = boto3.client('sts')
mfa_creds = client.get_session_token(
DurationSeconds=36000,
SerialNumber='<MFA serial number>',
TokenCode=mfa_otp
)
boto3 \
.client(service_name="<service name e.g. secretsmanager>",
region_name='us-west-2',
aws_access_key_id=mfa_creds['Credentials']['AccessKeyId'],
aws_secret_access_key=mfa_creds['Credentials']['SecretAccessKey'],
aws_session_token=mfa_creds['Credentials']['SessionToken'])
If you're not using MFA, you can omit those parts and it'll still work.
Upvotes: 4
Reputation: 51
The MFA method described below can be used for boto3 as well as the AWS CLI:
~/.aws/credentials
:
[local-keys]
aws_access_key_id = ABCDEFG
aws_secret_access_key = HIJKLMNOP
[stackoverflow]
role_arn = arn:aws:iam::123456789:role/RoleName
source_profile = local-keys
mfa_serial = arn:aws:iam:987654321:mfa/UserName
~/.aws/config
:
[profile stackoverflow]
region = us-east-1
Here is an example of how to use this in Python:
aws_MFA.py
:
#!/usr/bin/env python3
import boto3
session = boto3.Session(profile_name='stackoverflow')
ec2client = session.client('ec2')
Upvotes: 2
Reputation: 1063
You can use sts and get_session_token method to call use MFA with boto3. For this pre requirements is you should create a client object of sts and then call the function with mfa token. This will give you temporary credentials which you can use and these credentials are valid for 36 hours Code -
sts = boto3.client('sts')
response = sts.get_session_token(DurationSeconds=<time>, SerialNumber='string',TokenCode='string')
http://boto3.readthedocs.io/en/latest/reference/services/sts.html#STS.Client.get_session_token
Upvotes: 6