Skip to content

Conversation

propilideno
Copy link

Introduction

After my changes, I notice that I broke some features when I was trying to pass the session duration to my PROFILENAME.

$ avault76 login PROFILENAME -d 8h --debug                    
2025/08/16 16:37:20 aws-vault v7.6.0-rc1
2025/08/16 16:37:20 Using prompt driver: terminal
2025/08/16 16:37:20 [keyring] Considering backends: [secret-service]
2025/08/16 16:37:20 Loading config file /home/***/.aws/config
2025/08/16 16:37:20 Parsing config file /home/***/.aws/config
2025/08/16 16:37:20 profile PROFILENAME: using stored credentials
2025/08/16 16:37:20 profile PROFILENAME: skipping GetSessionToken because sessions are disabled for this profile
2025/08/16 16:37:20 profile PROFILENAME: using GetSessionToken (with MFA)
2025/08/16 16:37:20 profile PROFILENAME: using AssumeRole (chained MFA)
2025/08/16 16:37:20 Re-using cached credentials ****************ICW7 from sts.GetSessionToken, expires in 7h12m54.65693466s
aws-vault: error: login: operation error STS: AssumeRole, https response error StatusCode: 400, RequestID: 2d939bc8-4d67-4019-a676-2b87ed6e3bf8, api error ValidationError: The requested DurationSeconds exceeds the 1 hour session limit for roles assumed by role chaining.

In this example, you can notice that we are dealing it as a (chained MFA), that is not the truth.

Fixed

This problem occurs because the:

aws-vault/vault/vault.go

Lines 344 to 346 in 7500108

if c.ChainedFromProfile.AssumeRoleDuration > roleChainingMaximumDuration {
return false, fmt.Sprintf("duration %s in profile '%s' is greater than the AWS maximum %s for chaining MFA", c.ChainedFromProfile.AssumeRoleDuration, c.ChainedFromProfile.ProfileName, roleChainingMaximumDuration)
}

Notice that previously I was handling both methods as chained credentials, so to use this feature --duration, we must use the right method at the right time

I could get it working in both cases by using NewSessionTokenProvider in the SOURCE profile when we have config.ChainedFromProfile != nil

Cached Credentials

func (sk *SessionKeyring) lookupKeyName(key SessionMetadata) (string, error) {
allKeys, err := sk.Keyring.Keys()
if err != nil {
return key.String(), err
}
for _, keyName := range allKeys {
if strings.HasPrefix(keyName, key.StringForMatching()) {
return keyName, nil
}
}
return key.String(), ErrNotFound
}

After debugging, I found it:

 key github.com/99designs/aws-vault/v7/vault.SessionMetadata = vault.SessionMetadata {Type: "sts.GetSessionToken", ProfileName: "PROFILENAME", MfaSerial: "arn:aws:iam::***:mfa/***", Expiration: time.Time(0001-01-01T00:00:00Z){wall: 0, ext: 0, loc: *time.Location nil}}
   Type string = "sts.GetSessionToken"
   ProfileName string = "PROFILENAME"
   MfaSerial string = "arn:aws:iam::***:mfa/***"
  Expiration time.Time = time.Time(0001-01-01T00:00:00Z){wall: 0, ext: 0, loc: *time.Location nil}
    wall uint64 = 0 = 0x0
    ext int64 = 0
    loc *time.Location = *time.Location nil
strings.HasPrefix
  keyName:                 sts.AssumeRole,YWNr,YXJuOmF3czppYW06OjM4MDg2NTgzMDYxNTptZmEZQ,1755390794
  key.StringForMatching(): sts.GetSessionToken,YWNr,YXJuOmF3czppYW06OjM4MDg2NTgzMDYxNTptZmEZQ,

Notice that we only reuse if we use the same sts get credential method,
I tried to bypass it but got a 403 Forbidden. So I'll leave it unchanged, because i cannot find a way to do it better

Conclusion

aws-vault after a login without role chaining

Enter MFA code for arn:aws:iam::***:mfa/***: 
$ aws-vault list

Profile                          Credentials                      Sessions                                        
=======                          ===========                      ========                                        
PROFILENAME                      PROFILENAME                      sts.GetSessionToken:7h59m59s

aws-vault after a login with role chaining

$ aws-vault list

Profile                          Credentials                      Sessions                                        
=======                          ===========                      ========                                        
PROFILENAME                      PROFILENAME                      sts.AssumeRole:59m59s

aws-vault after both

$ aws-vault list

Profile                          Credentials                      Sessions                                        
=======                          ===========                      ========                                        
PROFILENAME                      PROFILENAME                      sts.GetSessionToken:7h59m18s, sts.AssumeRole:59m52s

So, we must provide Enter MFA code for arn:aws:iam::***:mfa/***: for each method.

@propilideno propilideno requested a review from mbevc1 as a code owner August 17, 2025 02:44
@mbevc1
Copy link

mbevc1 commented Aug 17, 2025

Thanks @propilideno ! I'll review this shorty, but would you mind opening a PR from a for of this repo instead of the upstream - I think that's why PR checks might be failing :)

@propilideno
Copy link
Author

Thanks @propilideno ! I'll review this shorty, but would you mind opening a PR from a for of this repo instead of the upstream - I think that's why PR checks might be failing :)

Hello @mbevc1, it's failing because I used merge: as the prefix of my commit message.
I did the merge from ByteNess/aws-vault. Because of that, I closed #86, which was the previous one that was failing due to merge conflicts. So, I created a branch named main; the previous one was based on master. I don't want to mix them because I will leave the PR to 99designs open.

@mbevc1 mbevc1 changed the title Fix credential method selection for chained vs non-chained MFA fix: credential method selection for chained vs non-chained MFA Aug 17, 2025
@mbevc1
Copy link

mbevc1 commented Aug 17, 2025

It's checking PR title, which I've fixed. But I think failure now might be related to integration access. I was wondering if we could test this with the for from here and now upstream. Mind, not a blocker for review of the change.

@propilideno
Copy link
Author

propilideno commented Aug 17, 2025

It's checking PR title, which I've fixed. But I think failure now might be related to integration access. I was wondering if we could test this with the for from here and now upstream. Mind, not a blocker for review of the change.

You're right, it seems to be it.
About the integration failure, i found it:

Troubleshooting

If you encounter an error message: Error: Resource not accessible by integration, adjust your repository settings. Go to your repository's settings, navigate to the "Actions" tab, and under the "General" section, update the "Workflow permissions" setting to "Read and Write Permission". This grants the necessary permissions for the action to function correctly.

If you need to use a different GitHub token instead of the default GITHUB_TOKEN, you can provide your own token as the token input to the action.

@mbevc1
Copy link

mbevc1 commented Aug 17, 2025

Yeah, I've already changed that but I reckon using other forks might break this 🤔 . Would you be able to give it a go to test this out?

@propilideno
Copy link
Author

propilideno commented Aug 17, 2025

It looks working for me: propilideno#1

I don't truly understand if it was the test you was looking for. Or if you asked to me to fork from ByteNess/aws-vault

@mbevc1
Copy link

mbevc1 commented Aug 17, 2025

So, back to the PR - this is now breaking source profile chaining where it keeps asking for MFA and not assuming the role:

Enter MFA code for arn:aws:iam::xxxxxxxxxxxxx:mfa/<user>: XXXXXX
2025/08/17 22:20:34 Re-using cached credentials ******************** from sts.GetSessionToken, expires in 35m20.33138408s
aws-vault: error: login: operation error STS: AssumeRole, get identity: get credentials: operation error STS: GetSessionToken, https response error StatusCode: 403, RequestID: 7fdc63fe-085c-410d-adee-312816d6b964, api error AccessDenied: Cannot call GetSessionToken with session credentials

@propilideno
Copy link
Author

So, back to the PR - this is now breaking source profile chaining where it keeps asking for MFA and not assuming the role:

Enter MFA code for arn:aws:iam::xxxxxxxxxxxxx:mfa/<user>: XXXXXX
2025/08/17 22:20:34 Re-using cached credentials ******************** from sts.GetSessionToken, expires in 35m20.33138408s
aws-vault: error: login: operation error STS: AssumeRole, get identity: get credentials: operation error STS: GetSessionToken, https response error StatusCode: 403, RequestID: 7fdc63fe-085c-410d-adee-312816d6b964, api error AccessDenied: Cannot call GetSessionToken with session credentials

Oh, you are right. I do not use this feature, so i couldn't notice it. I also runned unit tests but all cases it passed.

@propilideno
Copy link
Author

propilideno commented Aug 18, 2025

I'm busy right now, i'll review it ASAP

@mbevc1
Copy link

mbevc1 commented Aug 18, 2025

I'm busy right now, i'll review it ASAP

No worries mate!

@mbevc1
Copy link

mbevc1 commented Sep 16, 2025

Hey @propilideno 👋

Did you manage to review this?

@propilideno
Copy link
Author

Hey @propilideno 👋

Did you manage to review this?

Hello @mbevc1, I'll do it this weekend. The last one i was traveling.

@mbevc1
Copy link

mbevc1 commented Sep 18, 2025

No worries, thanks!

@propilideno
Copy link
Author

Hello @mbevc1, sorry for the slow response. I didn’t have time to work on my open source contributions this month.

I tested some scenarios, and everything below is working for me:

  • source chaining
  • role chaining
  • assume role with default duration
  • assume role with high duration

I'll wait for your tests to confirm if the issue is resolved.

Best Regards,
Lucas Almeida.

@mbevc1
Copy link

mbevc1 commented Sep 28, 2025

Hi @propilideno .

Thanks for revisiting this, but there still seems to be an issue using chained roles:

2025/09/28 22:33:59 profile 1a: sourcing credentials from profile sso
2025/09/28 22:33:59 profile sso: sourcing credentials from profile org
2025/09/28 22:33:59 profile org: using stored credentials
2025/09/28 22:33:59 profile org: using GetSessionToken (with MFA)
2025/09/28 22:33:59 profile sso: using GetSessionToken (with MFA)
2025/09/28 22:33:59 profile 1a: using AssumeRole (chained MFA)
Enter MFA code for arn:aws:iam::xxxxxxxx:mfa/xxxxx:

vs. now:

2025/09/28 22:33:51 profile 1a: sourcing credentials from profile sso
2025/09/28 22:33:51 profile sso: sourcing credentials from profile org
2025/09/28 22:33:51 profile org: using stored credentials
2025/09/28 22:33:51 profile org: using GetSessionToken (with MFA)
2025/09/28 22:33:51 profile sso: using AssumeRole (chained MFA)
2025/09/28 22:33:51 profile 1a: using AssumeRole (chained MFA)
2025/09/28 22:33:51 Re-using cached credentials ****************xxx from sts.GetSessionToken, expires in 7h57m14.903193993s
2025/09/28 22:33:51 Generated credentials ****************xxx using AssumeRole, expires in 59m59.73749645s
2025/09/28 22:33:51 Generated credentials ****************xxxx using AssumeRole, expires in 59m59.624275475s
2025/09/28 22:33:51 Requesting a signin token for session expiring in 59m59.624258132s

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants