aws / aws-sdk-go-v2

AWS SDK for the Go programming language.
https://aws.github.io/aws-sdk-go-v2/docs/
Apache License 2.0
2.54k stars 612 forks source link

Unable to authenticate using AWS Account with MFA enabled #2356

Closed meyuviofficial closed 2 months ago

meyuviofficial commented 9 months ago

Describe the bug

I'm trying to authenticate to an AWS account that has MFA enabled. But, I'm not able to do so because it's throwing error. Also, I'm not getting any examples or clear documentation for performing it.

I'm following the example mentioned in the official docs.

// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX - License - Identifier: Apache - 2.0
// snippet-start:[sts.go-v2.AssumeRole]
package main

import (
    "context"
    "fmt"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/sts"
)

// STSAssumeRoleAPI defines the interface for the AssumeRole function.
// We use this interface to test the function using a mocked service.
type STSAssumeRoleAPI interface {
    AssumeRole(ctx context.Context,
        params *sts.AssumeRoleInput,
        optFns ...func(*sts.Options)) (*sts.AssumeRoleOutput, error)
}

// TakeRole gets temporary security credentials to access resources.
// Inputs:
//
//  c is the context of the method call, which includes the AWS Region.
//  api is the interface that defines the method call.
//  input defines the input arguments to the service call.
//
// Output:
//
//  If successful, an AssumeRoleOutput object containing the result of the service call and nil.
//  Otherwise, nil and an error from the call to AssumeRole.
func TakeRole(c context.Context, api STSAssumeRoleAPI, input *sts.AssumeRoleInput) (*sts.AssumeRoleOutput, error) {
    return api.AssumeRole(c, input)
}

func main() {
    roleARN := "arn:aws:iam::<AccountId>:role/<RoleName>"
    sessionName := "<SessionName>"
    serialNumber := "arn:aws:iam::<AccountId>:mfa/<DeviceName>"

    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic("configuration error, " + err.Error())
    }

    client := sts.NewFromConfig(cfg)

    input := &sts.AssumeRoleInput{
        RoleArn:         &roleARN,
        RoleSessionName: &sessionName,
        SerialNumber:    &serialNumber,
        DurationSeconds: &[]int32{3600}[0],
        TokenCode:       &[]string{"<MFA Code>"}[0],
    }

    result, err := TakeRole(context.TODO(), client, input)
    if err != nil {
        fmt.Println("Got an error assuming the role:")
        fmt.Println(err)
        return
    }

    fmt.Println(result.AssumedRoleUser)
}

// snippet-end:[sts.go-v2.AssumeRole]

But, I'm not able to authenticate and I'm getting the below error always despite passing the MFA code.

Got an error assuming the role:
operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: d93830fb-f92e-4cdb-806f-cfdf116a6cef, api error InvalidClientTokenId: The security token included in the request is invalid.

Expected Behavior

Successfully authenticated to the AWS account.

Current Behavior

I'm not able to authenticate and I'm getting the below error always despite passing the MFA code.

Got an error assuming the role:
operation error STS: AssumeRole, https response error StatusCode: 403, RequestID: d93830fb-f92e-4cdb-806f-cfdf116a6cef, api error InvalidClientTokenId: The security token included in the request is invalid.

Reproduction Steps

Possible Solution

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

aws-auth github.com/aws/aws-sdk-go-v2@v1.22.1
aws-auth github.com/aws/aws-sdk-go-v2/config@v1.22.2
aws-auth github.com/aws/aws-sdk-go-v2/credentials@v1.15.1
aws-auth github.com/aws/aws-sdk-go-v2/feature/ec2/imds@v1.14.2
aws-auth github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1
aws-auth github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1
aws-auth github.com/aws/aws-sdk-go-v2/internal/ini@v1.5.1
aws-auth github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1
aws-auth github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0
aws-auth github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0
aws-auth github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0
aws-auth github.com/aws/smithy-go@v1.16.0
aws-auth go@1.21.3
github.com/aws/aws-sdk-go-v2@v1.22.1 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2@v1.22.1 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2@v1.22.1 github.com/jmespath/go-jmespath@v0.4.0
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/credentials@v1.15.1
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/feature/ec2/imds@v1.14.2
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/internal/ini@v1.5.1
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1
github.com/aws/aws-sdk-go-v2/config@v1.22.2 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/feature/ec2/imds@v1.14.2
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1
github.com/aws/aws-sdk-go-v2/credentials@v1.15.1 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1
github.com/aws/aws-sdk-go-v2/feature/ec2/imds@v1.14.2 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/feature/ec2/imds@v1.14.2 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/feature/ec2/imds@v1.14.2 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/internal/ini@v1.5.1 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0 github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1
github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1
github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/service/sso@v1.17.0 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0 github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1
github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1
github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/service/ssooidc@v1.19.0 github.com/google/go-cmp@v0.5.8
github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0 github.com/aws/aws-sdk-go-v2@v1.22.1
github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0 github.com/aws/aws-sdk-go-v2/internal/configsources@v1.2.1
github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0 github.com/aws/aws-sdk-go-v2/internal/endpoints/v2@v2.5.1
github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0 github.com/aws/aws-sdk-go-v2/service/internal/presigned-url@v1.10.1
github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0 github.com/aws/smithy-go@v1.16.0
github.com/aws/aws-sdk-go-v2/service/sts@v1.25.0 github.com/google/go-cmp@v0.5.8
github.com/aws/smithy-go@v1.16.0 github.com/google/go-cmp@v0.5.8
go@1.21.3 toolchain@go1.21.3

Compiler and Version used

go version go1.21.3 darwin/arm64

Operating System and version

Mac OS - Ventura - 13.6.1

cristim commented 8 months ago

I noticed something similar, may or may not be the same issue.

In my case the user and its MFA are defined in an account aaaaaaaaaaaaa and the assumed role is in another account, bbbbbbbbbbbb.

cfg, err := config.LoadDefaultConfig(context.TODO(),
    config.WithRegion(region),
)
if err != nil {
    log.Println("Error loading configuration profile:", err.Error())
}

gives Error loading configuration profile: assume role with MFA enabled, but AssumeRoleTokenProvider session option not set.

My AWS config looks like this, and it works well with AWS CLI:

[profile my-profile]
source_profile = users
role_arn=arn:aws:iam::bbbbbbbbbbbb:role/MyAssumedRole
mfa_serial = arn:aws:iam::aaaaaaaaaaaaa:mfa/my-mfa
region=us-east-1
RanVaknin commented 8 months ago

Hi @yuvarajselva .

Thank your for your patience. Admittedly I've never used this flow before, so this took some time to try and reproduce. Unfortunately Im not able to replicate the error. Im able to successfully use the MFA token to assume a role.

Here is my setup for comparison:

main.go:

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/sts"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO(),
        config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody),
        config.WithSharedConfigProfile("RanVakMfa"),
    )
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    stsClient := sts.NewFromConfig(cfg)
    roleArn := "arn:aws:iam::REDACTED:role/mfa-role"
    mfaSerialNumber := "arn:aws:iam::REDACTED:mfa/Pixel7"
    tokenCode := "123456" // 6 digit code supplied by google Authenticator app

    assumeRoleInput := &sts.AssumeRoleInput{
        RoleArn:         &roleArn,
        RoleSessionName: aws.String("session-name"),
        SerialNumber:    &mfaSerialNumber,
        TokenCode:       &tokenCode,
    }
    out, err := stsClient.AssumeRole(context.TODO(), assumeRoleInput)
    if err != nil {
        log.Fatalf("unable to assume role, %v", err)
    }

    fmt.Println(*out.AssumedRoleUser.Arn) // logs arn:aws:sts::REDACTED:assumed-role/mfa-role/session-name

aws.config:

[profile RanVakMfa]
region = us-east-1
output = json
mfa_serial = arn:aws:iam::REDACTED:mfa/Pixel7

aws.credentials:

[RanVak]
aws_access_key_id = REDACTED
aws_secret_access_key = REDACTED

Using the CLI I can quickly inspect my role and the the assume role policy document attached to it.

$ aws iam get-role --role-name mfa-role  
{
    "Role": {
        "Path": "/",
        "RoleName": "mfa-role",
        "RoleId": "REDACTED",
        "Arn": "arn:aws:iam::REDACTED:role/mfa-role",
        "CreateDate": "2023-12-06T00:22:58+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::REDACTED:user/RanVak"
                    },
                    "Action": "sts:AssumeRole",
                    "Condition": {
                        "Bool": {
                            "aws:MultiFactorAuthPresent": "true"
                        }
                    }
                }
            ]
        },
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {}
    }
}

My IAM user has MFA enabled and Google Authenticator on my actual mobile phone configured to be the MFA provider:

image

Raw Request and response logs:

SDK 2023/12/05 17:14:49 DEBUG Request
POST / HTTP/1.1
Host: sts.us-east-1.amazonaws.com
User-Agent: aws-sdk-go-v2/1.23.1 os/macos lang/go#1.19.1 md/GOOS#darwin md/GOARCH#arm64 api/sts#1.25.4
Content-Length: 204
Amz-Sdk-Invocation-Id: REDACTED
Amz-Sdk-Request: attempt=1; max=3
Authorization: AWS4-HMAC-SHA256 Credential={{aws_access_key_id of user RanVak}}/20231206/us-east-1/sts/aws4_request, SignedHeaders=amz-sdk-invocation-id;content-length;content-type;host;x-amz-date, Signature=REDACTED
Content-Type: application/x-www-form-urlencoded
X-Amz-Date: 20231206T011449Z
Accept-Encoding: gzip

Action=AssumeRole&
RoleArn=arn:aws:iam::REDACTED:role/mfa-role&
RoleSessionName=session-name&
SerialNumber=arn:aws:iam::REDACTED:mfa/Pixel7&
TokenCode=REDACTED&
Version=2011-06-15

SDK 2023/12/05 17:14:49 DEBUG Response
HTTP/1.1 200 OK
Content-Length: 1443
Content-Type: text/xml
Date: Wed, 06 Dec 2023 01:14:49 GMT
X-Amzn-Requestid: REDACTED

<AssumeRoleResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/">
  <AssumeRoleResult>
    <AssumedRoleUser>
      <AssumedRoleId>REDACTED:session-name</AssumedRoleId>
      <Arn>arn:aws:sts::REDACTED:assumed-role/mfa-role/session-name</Arn>
    </AssumedRoleUser>
    <Credentials>
      <AccessKeyId>REDACTED</AccessKeyId>
      <SecretAccessKey>REDACTED</SecretAccessKey>
      <SessionToken>REDACTED</SessionToken>
      <Expiration>2023-12-06T02:14:50Z</Expiration>
    </Credentials>
  </AssumeRoleResult>
  <ResponseMetadata>
    <RequestId>REDACTED</RequestId>
  </ResponseMetadata>
</AssumeRoleResponse>
arn:aws:sts::REDACTED:assumed-role/mfa-role/session-name

My guess is that one of the steps was not done correctly, or you did not setup your authentication device correctly. Can you please go over my code, and setup and see if it matches yours? Additionally, my code enables the raw request and response logger. You can use that to get an idea of the values you are sending over the wire and see at which part your application fails.

The part I see you were missing is to instruct the SDK to use a specific profile from your config file, but maybe you are doing so from an environment variable that is not visible in your code?

Thanks again, Ran~

cristim commented 8 months ago

In my setup I didn't specify the MFA serial in the Go code, since I had it in my profile.

And I think most people use profiles set in the environment rather than hardcoding them in code anyway.

So my code was something like this:

func connectEC2(region string) (*ec2.Client, error) {
        cfg, err := config.LoadDefaultConfig(context.TODO(),
        config.WithRegion(region),
    )
    if err != nil {
        log.Println("Error loading configuration profile:", err.Error())
        return nil, err
    }

    return ec2.NewFromConfig(cfg), nil
}

And got errors with a profile that has both mfa_serial and another source_profile assumed with IAM role

[profile test]
source_profile = default
role_arn = arn:aws:iam::xxxxxxx:role/DeveloperAccess
mfa_serial = arn:aws:iam::yyyyyyy:mfa/mfa

As a workaround I built this alternative MFA tool that runs as a credentials provider for my profile: https://github.com/LeanerCloud/assume_role_with_mfa

meyuviofficial commented 8 months ago

Hi @RanVaknin, Thanks for picking this up. I have tried your code but I'm getting the same error as before.

My Code:

package main

import (
    "context"
    "fmt"
    "log"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/sts"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO(),
        config.WithClientLogMode(aws.LogRequestWithBody|aws.LogResponseWithBody),
        config.WithSharedConfigProfile("sdu-dev-infra"),
    )
    if err != nil {
        log.Fatalf("unable to load SDK config, %v", err)
    }

    stsClient := sts.NewFromConfig(cfg)
    roleArn := "arn:aws:iam::765139991506:role/bea-platform-sre-iam-role"
    mfaSerialNumber := "arn:aws:iam::393751483396:mfa/Yuvi-Mobile"
    tokenCode := "022049" // 6 digit code supplied by google Authenticator app

    assumeRoleInput := &sts.AssumeRoleInput{
        RoleArn:         &roleArn,
        RoleSessionName: aws.String("session-name"),
        SerialNumber:    &mfaSerialNumber,
        TokenCode:       &tokenCode,
    }
    out, err := stsClient.AssumeRole(context.TODO(), assumeRoleInput)
    if err != nil {
        log.Fatalf("unable to assume role, %v", err)
    }

    fmt.Println(*out.AssumedRoleUser.Arn) // logs arn:aws:sts::REDACTED:assumed-role/mfa-role/session-name
}

Error Message:

2023/12/11 15:53:57 unable to load SDK config, assume role with MFA enabled, but AssumeRoleTokenProvider session option not set. exit status 1

AWS Config

[profile PARENT]
region = us-east-1
mfa_serial = arn:aws:iam::ACCOUNT_NUMBER:mfa/MY_DEVICE

[profile CHILD]
region = eu-west-1
role_arn = arn:aws:iam::ROLE_NUMBER:role/ROLE_NAME
mfa_serial = arn:aws:iam::ACCOUNT_NUMBER:mfa/MY_DEVICE
source_profile = PARENT

As you can see, I'm trying to login to the CHILD Profile as mentioned above where our resources are provisioned. These child profiles are nothing but child accounts used as DTAP environments (DEV, TST, PROD etc.)

This setup works perfectly fine in Python Boto3 and AWS CLI whereas the issue only lies with Go Lang SDK v2. Not sure, whether it works in v1. I haven't tried it yet.

AWS CREDENTIALS

cat ~/.aws/credentials

[PARENT]
aws_access_key_id = REDACTED
aws_secret_access_key = REDACTED

AWS CLI

I also tested with AWS CLI as you mentioned but I passed the profile along with it. And, it worked perfectly fine.

aws iam get-role --role-name $role_name --profile $profile
{
    "Role": {
        "Path": "/",
        "RoleName": "ROLE_NAME",
        "RoleId": "ROLE_ID",
        "Arn": "arn:aws:iam::ROLE_NUMBER:role/ROLE_NAME",
        "CreateDate": "YYYY-MM-DDTHH:MM:SS+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Sid": "idassume",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::ACCOUNT_NUMBER:root"
                    },
                    "Action": "sts:AssumeRole",
                    "Condition": {
                        "Bool": {
                            "aws:MultiFactorAuthPresent": "true"
                        }
                    }
                }
            ]
        },
        "Description": "ROLE DESCRIPTION",
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
            "LastUsedDate": "YYYY-MM-DDTHH:MM:SS+00:00",
            "Region": "eu-west-1"
        }
    }
}

PYTHON BOTO3

The same above setup works fine with boto3 as well using the below code.

# aws_service.py

import boto3
from botocore.config import Config

class aws_service:
    def __init__(self, service, region, profile):
        self.session = boto3.Session(profile_name=profile, region_name=region)
        self.client = self.session.client(
            service_name=service,
            config=Config(retries=dict(max_attempts=10, mode="standard")),
        )

The above python method can be called and it is working like a charm.

meyuviofficial commented 7 months ago

Do you have any updates on this?

meyuviofficial commented 4 months ago

Hi Team, Do you have any updates on this?

RanVaknin commented 3 months ago

Hi @meyuviofficial,

Thanks for your patience,

Referring to your last comment here, I tried replicating the behavior you described.

For example:

Credentials file

[RanVakMfa]
aws_access_key_id = REDACTED
aws_secret_access_key = REDACTED

Config file:

[profile RanVakMfa]
region = us-east-1
mfa_serial = arn:aws:iam::REDACTED:mfa/newpixel7

[profile RanVakMfaChild]
region = us-east-1
output = json
role_arn = arn:aws:iam::REDACTED:role/mfa-role
mfa_serial = arn:aws:iam::REDACTED:mfa/newpixel7
source_profile = RanVakMfa

But I'm not able to use assumeRole with the CLI using this setup:

$ aws sts assume-role --role-arn "arn:aws:iam::REDACTED:role/mfa-role" --role-session-name TestSession --serial-number "arn:aws:iam::REDACTED:mfa/newpixel7" --token-code 028266  --profile RanVakMfaChild

An error occurred (AccessDenied) when calling the AssumeRole operation: MultiFactorAuthentication failed, unable to validate MFA code.  Please verify your MFA serial number is valid and associated with this user.

As you can see, I'm trying to login to the CHILD Profile as mentioned above where our resources are provisioned. These child profiles are nothing but child accounts used as DTAP environments (DEV, TST, PROD etc.)

This setup works perfectly fine in Python Boto3 and AWS CLI whereas the issue only lies with Go Lang SDK v2. Not sure, whether it works in v1. I haven't tried it yet.

In your example you are not doing an assume role as you tried doing using the Go SDK in your issue description. Instead you are making a get role which is not really the right comparison:

aws iam get-role --role-name $role_name --profile $profile

its not clear which role you are getting here, and which profile you are using and its also not clear how this shows that your setup with a CHILD profile is actually working.

For all I know this is an equivalent of a general get-role command that is independent of how your config file is setup:

$ aws iam get-role --role-name mfa-role                                               

{
    "Role": {
        "Path": "/",
        "RoleName": "mfa-role",
        "RoleId": "REDACTED",
        "Arn": "arn:aws:iam::REDACTED:role/mfa-role",
        "CreateDate": "2023-12-06T00:22:58+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::REDACTED:user/RanVakMfa"
                    },
                    "Action": "sts:AssumeRole",
                    "Condition": {
                        "Bool": {
                            "aws:MultiFactorAuthPresent": "true"
                        }
                    }
                }
            ]
        },
        "MaxSessionDuration": 3600,
        "RoleLastUsed": {
            "LastUsedDate": "2023-12-06T00:38:07+00:00",
            "Region": "us-east-1"
        }
    }
}

Are you able to use assumerole using this config file setup? Any other information you can provide would be helpful.

Thanks, Ran~

github-actions[bot] commented 2 months ago

This issue has not received a response in 1 week. If you want to keep this issue open, please just leave a comment below and auto-close will be canceled.