Skip to content

Login session (aws login) credentials rejected when used as source_profile for an assume-role profile #3446

Description

@alext

Acknowledgements

Describe the bug

aws-sdk-go-v2/config added aws login (login session) credential support in v1.32.0. It works when a profile uses login_session directly. But when a profile that uses login_session is referenced as the source_profile of an assume-role profile, LoadDefaultConfig fails with "failed to load assume role , of profile , ". The AWS CLI and boto3 resolve the identical configuration successfully.

Regression Issue

  • Select this option if this issue appears to be a regression.

Expected Behavior

A profile using login_session should be a valid credential source for an assume-role chain via source_profile, consistent with the AWS CLI/boto3 and with how SSO, credential_process, and web_identity_token_file are already accepted.

Current Behavior

Loading config via config.LoadDefaultConfig(ctx) returns an error:

failed to load assume role arn:aws:iam::111111111111:role/MyRole, of profile users, <nil>

Reproduction Steps

Given the following in ~/.aws/config:

[default]
region=eu-west-2
role_arn = arn:aws:iam::111111111111:role/MyRole
source_profile = users

[profile users]
login_session = arn:aws:iam::222222222222:user/user_name
region = eu-west-2

After completing aws login --profile users, the AWS cli works - aws sts get-caller-identity returns session details, however running the collowing code errors as above

func main() {
    ctx := context.Background()
    cfg, err := config.LoadDefaultConfig(ctx)
    if err != nil {
        log.Fatalln("Error loading AWS config", err)
    }

    identityOutput, err := sts.NewFromConfig(cfg).GetCallerIdentity(ctx, &sts.GetCallerIdentityInput{})
    if err != nil {
        log.Fatalln("Error fetching caller identity", err)
    }

    fmt.Println(*identityOutput.Arn)
}

Possible root cause

In config/shared_config.go, setFromIniSections validates the linked source profile and returns SharedConfigAssumeRoleError (with a nil wrapped Err, hence the <nil>) when hasCredentials() is false:

if !srcCfg.hasCredentials() {
    return SharedConfigAssumeRoleError{ RoleARN: c.RoleARN, Profile: c.SourceProfileName }
}

hasCredentials() never considers LoginSession:

func (c *SharedConfig) hasCredentials() bool {
    switch {
    case len(c.SourceProfileName) != 0:
    case len(c.CredentialSource) != 0:
    case len(c.CredentialProcess) != 0:
    case len(c.WebIdentityTokenFile) != 0:
    case c.hasSSOConfiguration():
    case c.Credentials.HasKeys():
    default:
        return false
    }
    return true
}

resolveCredsFromProfile has support for LoginSession being populated on SharedConfig though, so it looks like it would work if it got that far.

Possible Solution

Add a login-session case to hasCredentials():

  case len(c.LoginSession) != 0:

Also consider giving the !srcCfg.hasCredentials() branch a descriptive Err rather than emitting <nil>.

Additional Information/Context

No response

AWS Go SDK V2 Module Versions Used

github.com/aws/aws-sdk-go-v2 v1.42.0
github.com/aws/aws-sdk-go-v2/config v1.32.25
github.com/aws/aws-sdk-go-v2/service/sts v1.43.3

Compiler and Version used

go version go1.26.1 linux/amd64

Operating System and version

Debian 13 - Linux 6.12.86+deb13-amd64

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugThis issue is a bug.needs-triageThis issue or PR still needs to be triaged.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions