Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to assume role with MFA #1080

Closed
cbarbour opened this issue Nov 14, 2016 · 3 comments
Closed

Unable to assume role with MFA #1080

cbarbour opened this issue Nov 14, 2016 · 3 comments

Comments

@cbarbour
Copy link

cbarbour commented Nov 14, 2016

I'm unable to issue a sts:assume_role query with botocore when MFA is enabled. The apparent cause is that Boto is not passing all required security credentials to AWS.

I am able to assume the role using MFA using the Go libraries or via the web API using the same credentials.

My client is: "Botocore/1.4.70 Python/3.5.2 Darwin/15.5.0",

Here's the basic commands I'm issuing:

os.environ['AWS_PROFILE']='EXAMPLE'
session=botocore.session.get_session()
credential_provider=session.get_component('credential_provider')
credentials=credential_provider.load_credentials()

client=session.create_client(aws_access_key_id=credentials.access_key,
    aws_secret_access_key=credentials.secret_key, service_name='sts')

client.get_session_token(SerialNumber='arn:aws:iam::EXAMPLE:mfa/EXAMPLE',
    TokenCode='123456')

mfa_client=session.create_client(aws_access_key_id='EXAMPLEACCESSKEYID',
    aws_secret_access_key='EXAMPLESECRETACCESSKEY',
    aws_session_Token='EXAMPLESESSIONTOKEN,
    service_name='sts')

mfa_client.assume_role(RoleArn='arn:aws:iam::EXAMPLE:/role/EXAMPLE',
    RoleSessionName='EXAMPLE',
    SerialNumber='arn:aws:iam::EXAMPLE:mfa/EXAMPLE',
    TokenCode='633369')

The result is an access denied error, and the following cloudtrail log:

        {
            "awsRegion": "us-east-1",
            "errorCode": "AccessDenied",
            "errorMessage": "Not authorized to perform sts:AssumeRole",
            "eventID": "c3ee3dab-c89b-485d-92e7-4cbf2f265909",
            "eventName": "AssumeRole",
            "eventSource": "sts.amazonaws.com",
            "eventTime": "2016-11-14T19:38:05Z",
            "eventType": "AwsApiCall",
            "eventVersion": "1.05",
            "recipientAccountId": "EXAMPLE",
            "requestID": "dd25896d-aaa1-11e6-a430-477a3a0eb10f",
            "requestParameters": null,
            "responseElements": null,
            "sourceIPAddress": "EXAMPLE",
            "userAgent": "Botocore/1.4.70 Python/3.5.2 Darwin/15.5.0",
            "userIdentity": {
                "accessKeyId": "EXAMPLE",
                "accountId": "EXAMPLE",
                "arn": "arn:aws:iam::EXAMPLE:user/EXAMPLE",
                "principalId": "EXAMPLE",
                "sessionContext": {
                    "attributes": {
                        "creationDate": "2016-11-14T19:28:10Z",
                        "mfaAuthenticated": "true"
                    }
                },
                "type": "IAMUser",
                "userName": "EXAMPLE"
            }
        }

Calling assume_role without a MFA token also fails:

mfa_client.assume_role(RoleArn='arn:aws:iam::EXAMPLE:/role/EXAMPLE', RoleSessionName='EXAMPLE')

If I configure my environment with the mfa_client tokens, Terraform is able to assume the EXAMPLE role just fine, producing the following log entry:

        {
            "awsRegion": "us-east-1",
            "eventID": "7c51a038-02bc-436d-86ef-c37f3da0d332",
            "eventName": "AssumeRole",
            "eventSource": "sts.amazonaws.com",
            "eventTime": "2016-11-14T19:36:45Z",
            "eventType": "AwsApiCall",
            "eventVersion": "1.05",
            "recipientAccountId": "EXAMPLE",
            "requestID": "ad66f098-aaa1-11e6-a93b-696e5566ee92",
            "requestParameters": {
                "durationSeconds": 900,
                "roleArn": "arn:aws:iam::EXAMPLE:role/EXAMPLE",
                "roleSessionName": "EXAMPLE"
            },
            "resources": [
                {
                    "ARN": "arn:aws:iam::EXAMPLE:role/EXAMPLE",
                    "accountId": "EXAMPLE",
                    "type": "AWS::IAM::Role"
                }
            ],
            "responseElements": {
                "assumedRoleUser": {
                    "arn": "arn:aws:sts::EXAMPLE:assumed-role/EXAMPLE/EXAMPLE",
                    "assumedRoleId": "EXAMPLE:EXAMPLE"
                },
                "credentials": {
                    "accessKeyId": "EXAMPLE",
                    "expiration": "Nov 14, 2016 7:51:45 PM",
                    "sessionToken": "EXAMPLE"
                }
            },
            "sourceIPAddress": "EXAMPLE",
            "userAgent": "aws-sdk-go/1.4.17 (go1.7.3; darwin; amd64)",
            "userIdentity": {
                "accessKeyId": "EXAMPLE",
                "accountId": "EXAMPLE",
                "arn": "arn:aws:iam::EXAMPLE:user/EXAMPLE",
                "principalId": "EXAMPLE",
                "sessionContext": {
                    "attributes": {
                        "creationDate": "2016-11-14T19:28:10Z",
                        "mfaAuthenticated": "true"
                    }
                },
                "type": "IAMUser",
                "userName": "EXAMPLE"
            }
        }

I've also tried using using the mfa_serial and source_profile configuration keys in .aws/credentials, and had no success.

@JordonPhillips
Copy link
Contributor

I really would not recommend manually using the credential provider. You can give a profile name when creating a session: botocore.session.Session(profile='foo'). The way you're constructing your client will break the auto-renewal.

To be clear, configuring a profile as described here and doing the following doesn't work:

from botocore.session import Session

sess = Session(profile='example')
client = sess.create_client('s3')
client.list_buckets()

(assuming that the role is configured for s3 access)

@cbarbour
Copy link
Author

To be clear, the included code is for reproduction purposes only; I'm not attempting to use the included code in any project.

I actually ran into this issue while attempting to assume a role using the AWS cli, and did my best to trace the issue down. My investigation lead to this point, but I don't have a deep enough familiarity with Botocore to investigate further.

Here's the aws-cli bug I filed: aws/aws-cli#2279

As per the linked bug report, the sts:AssumeRole call fails even when profiles are properly configured for MFA.

As far as I can tell, the issue is MFA specific; I can attempt to reproduce using a non-MFA authenticated role if that helps.

@JordonPhillips
Copy link
Contributor

Let's consolidate and track this issue over in the cli.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants