fix: credential method selection and role chaining duration handling#333
fix: credential method selection and role chaining duration handling#333propilideno wants to merge 11 commits intoByteNess:mainfrom
Conversation
… prompting source mfa
6e9bb03 to
7af6057
Compare
|
I did a rebase and force-pushed signed commits to pass on the pipeline verification. |
|
Thanks @propilideno . I'll try again my chain assume roles that were regressing last time and get back to you. One small comment; could oyu perhaps add a test for the duration cap behavior. The three unit tests cover method selection, but there's no test asserting that a chained AssumeRole duration is capped to 1 hour when a longer duration is requested. The smoke test confirms it works manually, but a unit/integration test here would make the cap logic regression-proof going forward. |
|
Hey @mbevc1. |
|
Before #333 After #333 |
|
Hi @propilideno and thanks for adding the tests. I've re-tested my role chaining and it's still breaking and keep asking for MFA like here: #87 (comment) |
Hey @mbevc1, |
|
Sure, this is config I'm testing with: And running |
mbevc1
left a comment
There was a problem hiding this comment.
Let's address the role chaining issue before we merge this. Thanks for your effort @propilideno
|
Hey @mbevc1,
My tests |
|
So there is |
I closed #87 because the repository left the fork network in the meantime, and that PR got into a deadlock where GitHub was no longer reflecting the real diff/check state correctly.
So I re-forked ByteNess/aws-vault and opened this clean PR with only the final changes.
Introduction
In #75, I fixed the original regression: aws-vault v7 was missing the
GetSessionTokenstep that v6 used beforeAssumeRolein real MFA role chaining scenarios.That fix solved the broken role chaining, but while I was trying to improve the behavior afterwards, I ended up mistreating some flows as
(chained MFA).So the real follow-up problem was the credential method selection.
This PR keeps the original role chaining fix from #75, but now uses the right STS method at the right time.
Fixed
(chained MFA)source_profileof another role profile, aws-vault still doesGetSessionTokenfirst and thenAssumeRole--duration, instead of failing, aws-vault now uses that duration to get the source token session and caps chainedAssumeRolecalls to AWS 1 hour limitAWS behavior
This implementation follows AWS STS behavior for each credential method.
GetSessionTokenis the STS API AWS provides to obtain MFA-authenticated temporary credentials from IAM user credentials. AWS documents that for IAM users the duration can range from 15 minutes up to 36 hours, with 12 hours as the default. This is the credential method that preserves MFA-authenticated source credentials before the next step in the flow.https://docs.aws.amazon.com/STS/latest/APIReference/API_GetSessionToken.html
https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_sts-comparison.html
AssumeRoleis the STS API AWS uses for the role session itself. AWS documents thatDurationSecondscan range from 15 minutes up to the maximum session duration configured on the role, with 1 hour as the default and up to 12 hours depending on the role setting.https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html
AWS also documents that role chaining has a hard 1 hour limit for
AssumeRole, even if the requested duration is higher. In other words, a longer source session does not change the 1 hour limit for chained role assumptions.https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-chaining
These limits are what drive the behavior in this PR:
GetSessionTokenandAssumeRoleare not interchangeable, and the duration rules are different depending on which STS method is being used.Tests
The unit tests in this PR are focused on the real bug here: credential method selection.
TestDirectRoleLoginDoesNotUseGetSessionToken(chained MFA)TestRoleChainingMfaUsesGetSessionTokenBeforeAssumeRolesource_profileof another role profile with the same MFA deviceGetSessionTokenfirst and then performs the chainedAssumeRoleflowTestNonRoleChainingFlowDoesNotUseChainedMfaPath(chained MFA)So these tests are checking the exact decision points that caused the regression.
Test results by milestone
Before #75, the original role chaining regression is reproduced by:
After #75, role chaining is fixed, but the follow-up regression is reproduced by:
With this PR, all three tests pass.
Smoke tests
I also validated this with smoke tests in my own scenarios.
MFA-authenticated IAM user
GetSessionTokenaccepts up to 36 hours for an MFA-authenticated IAM user session, so36hworks and37hfails with the expected AWS validation error.IAM role
For a direct role login,
AssumeRolefollows the role duration limit. In this case12hworks and13hfails with the expected AWS validation error.Role chaining
For role chaining, the source MFA session keeps the requested duration, while both
AssumeRolecalls are limited to 1 hour.Source profile chaining with a role
This is a source-profile chain with a role target, not a role-chaining MFA flow, so it should go directly to
AssumeRole.Source profile chaining without a role
This is also not a role-chaining MFA flow. The target does not assume a role, so the result is a plain
GetSessionTokensession for the target profile.Related